CONVERT

28/06/2006 - 15:52 por David Baez | Informe spam
De antemano muchas gracias.

Es que las sentencias son de un proveedor y necesitábamos mas información
que nos ayudara a darle una respuesta ya que el proveedor tenia la duda o
quería saber por que en algunas ocasiones realiza por el CONVERT por el campo
de comparación y en otras ocasiones realiza el CONVERT sobre la variable.

Cabe de aclarar que son sentencias diferentes cuando el plan de ejecución
realiza el CONVERT por el campo y el CONVERT por la variable.

De todas formas ya le recomendamos al proveedor que modifique las variables
de entrada y que sean del mismo tipo.

Esta realiza el convert por el CAMPO

exec sp_executesql N'SELECT
COF_CONC,COF_CTEC,COF_CLIB,COF_CSEC,COF_CPRC,ITE_CONT,COF_CONT FROM
IN_COFIN,IN_UBICA
WHERE IN_COFIN.EMP_CODI = @P1
AND IN_COFIN.INS_CONT = @P2
AND IN_COFIN.BOD_CODI = @P3
AND COF_CONC <> 0
AND (((COF_CONC = 3 AND COF_INRE = ''T''))
OR COF_CONC >= 0)
AND COF_INRE <> ''J''
AND IN_COFIN.EMP_CODI = IN_UBICA.EMP_CODI
AND IN_COFIN.UBI_CONT = IN_UBICA.UBI_CONT
AND IN_UBICA.TRU_CONT =@P4', N'@P1 money,@P2 money,@P3 money,@P4 money',
$26.0000, $1.0000, $1.0000, $900.0000

Esta realiza el convert por la variable

exec sp_executesql N'SELECT
PE_MDPED.EMP_CODI,PE_MDPED.MDP_CONT,PE_MDPED.PED_CONT,PE_MDPED.PRO_CONT,PE_MDPED.PRO_SUST,PE_MDPED.BOD_CONT,PE_MDPED.LIP_CONT,PE_MDPED.UNI_CODI,PE_MDPED.MDP_CANT,PE_MDPED.MDP_PRLI,

PE_MDPED.MDP_VALO,PE_MDPED.MDP_PRMA,PE_MDPED.MDP_TIDE,PE_MDPED.MDP_PVDE,PE_MDPED.MDP_VADE,PE_MDPED.MDP_DEPP,PE_MDPED.MDP_DESC,PE_MDPED.MDP_CPIK,PE_MDPED.MDP_CCON,PE_MDPED.MDP_CDES,

PE_MDPED.MDP_CFAC,PE_MDPED.MDP_PROM,PE_MDPED.MDP_BONI,PE_MDPED.MDP_ESTA,PE_MDPED.MDP_ORDC,

PE_PEDIM.INS_CONT,PE_PEDIM.TOP_CODI,PE_PEDIM.ACT_CONT,PE_PEDIM.MON_CODI,FA_CLIEN.TCL_CODI,PE_PEDIM.UNN_CONT,PE_PEDIM.CLI_CODI,PE_PEDIM.DCL_CODD,PE_PEDIM.PED_FECH,PE_PEDIM.PED_FECH,IN_PRODU.PRO_CODI,IN_BODEG.BOD_CODI,IN_PRODU.PRO_CLNG,

FA_CLIEN.CLI_PRIO,FA_CLIEN.CLI_SUIT,FA_CLIEN.CLI_MULT,FA_CLIEN.CLI_DIAL,FA_CLIEN.CLI_DVIG,FA_CLIEN.CLI_PLIN,FA_CLIEN.CLI_FPEC,FA_CLIEN.BOD_DEST,
PE_PEDIM.PED_NUME,FA_CLIEN.CLI_BACK
FROM PE_MDPED,PE_PEDIM,IN_PRODU,IN_BODEG,PE_CLASE,FA_CLIEN,PE_MTIPO
WHERE PE_MDPED.EMP_CODI = PE_PEDIM.EMP_CODI
AND PE_MDPED.PED_CONT = PE_PEDIM.PED_CONT
AND PE_MDPED.EMP_CODI = IN_PRODU.EMP_CODI
AND PE_MDPED.PRO_CONT = IN_PRODU.PRO_CONT
AND PE_MDPED.EMP_CODI = IN_BODEG.EMP_CODI
AND PE_MDPED.BOD_CONT = IN_BODEG.BOD_CONT
AND PE_PEDIM.EMP_CODI = PE_CLASE.EMP_CODI
AND PE_PEDIM.CLA_CONT = PE_CLASE.CLA_CONT
AND PE_PEDIM.EMP_CODI = FA_CLIEN.EMP_CODI
AND PE_PEDIM.CLI_CODI = FA_CLIEN.CLI_CODI
AND PE_PEDIM.EMP_CODI = PE_MTIPO.EMP_CODI
AND PE_PEDIM.MTI_CONT = PE_MTIPO.MTI_CONT
AND PE_CLASE.CLA_PIKI = ''S''
AND PE_MTIPO.MTI_SALD = ''S''
AND PE_MDPED.MDP_BONI = ''N''
AND PE_MDPED.PRO_CONT <> 0
AND (PE_MDPED.MDP_ESTA = ''G'')
AND PE_PEDIM.EMP_CODI = @P1
AND PE_PEDIM.PED_NUME BETWEEN @P2 AND @P3
ORDER BY FA_CLIEN.CLI_PRIO,PE_PEDIM.PED_CONT,PE_PEDIM.PED_FECH', N'@P1
money,@P2 money,@P3 money', $94.0000, $8288.0000, $8288.0000

Preguntas similare

Leer las respuestas

#1 David Baez
28/06/2006 - 16:01 | Informe spam
Buenos Dias

A esta pregunta ya me respondieron, muchas gracias.

"David Baez" escribió:

De antemano muchas gracias.

Es que las sentencias son de un proveedor y necesitábamos mas información
que nos ayudara a darle una respuesta ya que el proveedor tenia la duda o
quería saber por que en algunas ocasiones realiza por el CONVERT por el campo
de comparación y en otras ocasiones realiza el CONVERT sobre la variable.

Cabe de aclarar que son sentencias diferentes cuando el plan de ejecución
realiza el CONVERT por el campo y el CONVERT por la variable.

De todas formas ya le recomendamos al proveedor que modifique las variables
de entrada y que sean del mismo tipo.

Esta realiza el convert por el CAMPO

exec sp_executesql N'SELECT
COF_CONC,COF_CTEC,COF_CLIB,COF_CSEC,COF_CPRC,ITE_CONT,COF_CONT FROM
IN_COFIN,IN_UBICA
WHERE IN_COFIN.EMP_CODI = @P1
AND IN_COFIN.INS_CONT = @P2
AND IN_COFIN.BOD_CODI = @P3
AND COF_CONC <> 0
AND (((COF_CONC = 3 AND COF_INRE = ''T''))
OR COF_CONC >= 0)
AND COF_INRE <> ''J''
AND IN_COFIN.EMP_CODI = IN_UBICA.EMP_CODI
AND IN_COFIN.UBI_CONT = IN_UBICA.UBI_CONT
AND IN_UBICA.TRU_CONT =@P4', N'@P1 money,@P2 money,@P3 money,@P4 money',
$26.0000, $1.0000, $1.0000, $900.0000

Esta realiza el convert por la variable

exec sp_executesql N'SELECT
PE_MDPED.EMP_CODI,PE_MDPED.MDP_CONT,PE_MDPED.PED_CONT,PE_MDPED.PRO_CONT,PE_MDPED.PRO_SUST,PE_MDPED.BOD_CONT,PE_MDPED.LIP_CONT,PE_MDPED.UNI_CODI,PE_MDPED.MDP_CANT,PE_MDPED.MDP_PRLI,

PE_MDPED.MDP_VALO,PE_MDPED.MDP_PRMA,PE_MDPED.MDP_TIDE,PE_MDPED.MDP_PVDE,PE_MDPED.MDP_VADE,PE_MDPED.MDP_DEPP,PE_MDPED.MDP_DESC,PE_MDPED.MDP_CPIK,PE_MDPED.MDP_CCON,PE_MDPED.MDP_CDES,

PE_MDPED.MDP_CFAC,PE_MDPED.MDP_PROM,PE_MDPED.MDP_BONI,PE_MDPED.MDP_ESTA,PE_MDPED.MDP_ORDC,

PE_PEDIM.INS_CONT,PE_PEDIM.TOP_CODI,PE_PEDIM.ACT_CONT,PE_PEDIM.MON_CODI,FA_CLIEN.TCL_CODI,PE_PEDIM.UNN_CONT,PE_PEDIM.CLI_CODI,PE_PEDIM.DCL_CODD,PE_PEDIM.PED_FECH,PE_PEDIM.PED_FECH,IN_PRODU.PRO_CODI,IN_BODEG.BOD_CODI,IN_PRODU.PRO_CLNG,

FA_CLIEN.CLI_PRIO,FA_CLIEN.CLI_SUIT,FA_CLIEN.CLI_MULT,FA_CLIEN.CLI_DIAL,FA_CLIEN.CLI_DVIG,FA_CLIEN.CLI_PLIN,FA_CLIEN.CLI_FPEC,FA_CLIEN.BOD_DEST,
PE_PEDIM.PED_NUME,FA_CLIEN.CLI_BACK
FROM PE_MDPED,PE_PEDIM,IN_PRODU,IN_BODEG,PE_CLASE,FA_CLIEN,PE_MTIPO
WHERE PE_MDPED.EMP_CODI = PE_PEDIM.EMP_CODI
AND PE_MDPED.PED_CONT = PE_PEDIM.PED_CONT
AND PE_MDPED.EMP_CODI = IN_PRODU.EMP_CODI
AND PE_MDPED.PRO_CONT = IN_PRODU.PRO_CONT
AND PE_MDPED.EMP_CODI = IN_BODEG.EMP_CODI
AND PE_MDPED.BOD_CONT = IN_BODEG.BOD_CONT
AND PE_PEDIM.EMP_CODI = PE_CLASE.EMP_CODI
AND PE_PEDIM.CLA_CONT = PE_CLASE.CLA_CONT
AND PE_PEDIM.EMP_CODI = FA_CLIEN.EMP_CODI
AND PE_PEDIM.CLI_CODI = FA_CLIEN.CLI_CODI
AND PE_PEDIM.EMP_CODI = PE_MTIPO.EMP_CODI
AND PE_PEDIM.MTI_CONT = PE_MTIPO.MTI_CONT
AND PE_CLASE.CLA_PIKI = ''S''
AND PE_MTIPO.MTI_SALD = ''S''
AND PE_MDPED.MDP_BONI = ''N''
AND PE_MDPED.PRO_CONT <> 0
AND (PE_MDPED.MDP_ESTA = ''G'')
AND PE_PEDIM.EMP_CODI = @P1
AND PE_PEDIM.PED_NUME BETWEEN @P2 AND @P3
ORDER BY FA_CLIEN.CLI_PRIO,PE_PEDIM.PED_CONT,PE_PEDIM.PED_FECH', N'@P1
money,@P2 money,@P3 money', $94.0000, $8288.0000, $8288.0000



Respuesta Responder a este mensaje
#2 Alejandro Mesa
28/06/2006 - 16:03 | Informe spam
David Baez,

Cual es tu inquietud?

Los parametros deben ser del mismo tipo que el de las columnas que
participan en la expresion.
Puedes cambiar el tipo de los parametros o hacer un "convert" explicito.

...
where c1 = convert(money, @c1)

Es muy importante que el "convert" ocurra sobre el parametro y no sobre la
columna,
pues de lo contrario SQL Server no hara un uso adecuado de los indices, por
la columna en question,
en casos de estos existir.


AMB

"David Baez" wrote:

De antemano muchas gracias.

Es que las sentencias son de un proveedor y necesitábamos mas información
que nos ayudara a darle una respuesta ya que el proveedor tenia la duda o
quería saber por que en algunas ocasiones realiza por el CONVERT por el campo
de comparación y en otras ocasiones realiza el CONVERT sobre la variable.

Cabe de aclarar que son sentencias diferentes cuando el plan de ejecución
realiza el CONVERT por el campo y el CONVERT por la variable.

De todas formas ya le recomendamos al proveedor que modifique las variables
de entrada y que sean del mismo tipo.

Esta realiza el convert por el CAMPO

exec sp_executesql N'SELECT
COF_CONC,COF_CTEC,COF_CLIB,COF_CSEC,COF_CPRC,ITE_CONT,COF_CONT FROM
IN_COFIN,IN_UBICA
WHERE IN_COFIN.EMP_CODI = @P1
AND IN_COFIN.INS_CONT = @P2
AND IN_COFIN.BOD_CODI = @P3
AND COF_CONC <> 0
AND (((COF_CONC = 3 AND COF_INRE = ''T''))
OR COF_CONC >= 0)
AND COF_INRE <> ''J''
AND IN_COFIN.EMP_CODI = IN_UBICA.EMP_CODI
AND IN_COFIN.UBI_CONT = IN_UBICA.UBI_CONT
AND IN_UBICA.TRU_CONT =@P4', N'@P1 money,@P2 money,@P3 money,@P4 money',
$26.0000, $1.0000, $1.0000, $900.0000

Esta realiza el convert por la variable

exec sp_executesql N'SELECT
PE_MDPED.EMP_CODI,PE_MDPED.MDP_CONT,PE_MDPED.PED_CONT,PE_MDPED.PRO_CONT,PE_MDPED.PRO_SUST,PE_MDPED.BOD_CONT,PE_MDPED.LIP_CONT,PE_MDPED.UNI_CODI,PE_MDPED.MDP_CANT,PE_MDPED.MDP_PRLI,

PE_MDPED.MDP_VALO,PE_MDPED.MDP_PRMA,PE_MDPED.MDP_TIDE,PE_MDPED.MDP_PVDE,PE_MDPED.MDP_VADE,PE_MDPED.MDP_DEPP,PE_MDPED.MDP_DESC,PE_MDPED.MDP_CPIK,PE_MDPED.MDP_CCON,PE_MDPED.MDP_CDES,

PE_MDPED.MDP_CFAC,PE_MDPED.MDP_PROM,PE_MDPED.MDP_BONI,PE_MDPED.MDP_ESTA,PE_MDPED.MDP_ORDC,

PE_PEDIM.INS_CONT,PE_PEDIM.TOP_CODI,PE_PEDIM.ACT_CONT,PE_PEDIM.MON_CODI,FA_CLIEN.TCL_CODI,PE_PEDIM.UNN_CONT,PE_PEDIM.CLI_CODI,PE_PEDIM.DCL_CODD,PE_PEDIM.PED_FECH,PE_PEDIM.PED_FECH,IN_PRODU.PRO_CODI,IN_BODEG.BOD_CODI,IN_PRODU.PRO_CLNG,

FA_CLIEN.CLI_PRIO,FA_CLIEN.CLI_SUIT,FA_CLIEN.CLI_MULT,FA_CLIEN.CLI_DIAL,FA_CLIEN.CLI_DVIG,FA_CLIEN.CLI_PLIN,FA_CLIEN.CLI_FPEC,FA_CLIEN.BOD_DEST,
PE_PEDIM.PED_NUME,FA_CLIEN.CLI_BACK
FROM PE_MDPED,PE_PEDIM,IN_PRODU,IN_BODEG,PE_CLASE,FA_CLIEN,PE_MTIPO
WHERE PE_MDPED.EMP_CODI = PE_PEDIM.EMP_CODI
AND PE_MDPED.PED_CONT = PE_PEDIM.PED_CONT
AND PE_MDPED.EMP_CODI = IN_PRODU.EMP_CODI
AND PE_MDPED.PRO_CONT = IN_PRODU.PRO_CONT
AND PE_MDPED.EMP_CODI = IN_BODEG.EMP_CODI
AND PE_MDPED.BOD_CONT = IN_BODEG.BOD_CONT
AND PE_PEDIM.EMP_CODI = PE_CLASE.EMP_CODI
AND PE_PEDIM.CLA_CONT = PE_CLASE.CLA_CONT
AND PE_PEDIM.EMP_CODI = FA_CLIEN.EMP_CODI
AND PE_PEDIM.CLI_CODI = FA_CLIEN.CLI_CODI
AND PE_PEDIM.EMP_CODI = PE_MTIPO.EMP_CODI
AND PE_PEDIM.MTI_CONT = PE_MTIPO.MTI_CONT
AND PE_CLASE.CLA_PIKI = ''S''
AND PE_MTIPO.MTI_SALD = ''S''
AND PE_MDPED.MDP_BONI = ''N''
AND PE_MDPED.PRO_CONT <> 0
AND (PE_MDPED.MDP_ESTA = ''G'')
AND PE_PEDIM.EMP_CODI = @P1
AND PE_PEDIM.PED_NUME BETWEEN @P2 AND @P3
ORDER BY FA_CLIEN.CLI_PRIO,PE_PEDIM.PED_CONT,PE_PEDIM.PED_FECH', N'@P1
money,@P2 money,@P3 money', $94.0000, $8288.0000, $8288.0000



Respuesta Responder a este mensaje
#3 David Baez
28/06/2006 - 16:13 | Informe spam
Buenos Dias

Gracias alejandro de antemano, es que me equivoque y cree otra pregunta y
debia ser una respusta. La pregunta la puse ayer y tenia el mismo asunto.

Ya se le informo al proveedor que la solucion es que arreglen las consultas,
mi duda es como determina el motor en donde realizar el CONVERT si lo deber
realizar por el campo de comparacion o por la vaiable de entrada.



"Alejandro Mesa" escribió:

David Baez,

Cual es tu inquietud?

Los parametros deben ser del mismo tipo que el de las columnas que
participan en la expresion.
Puedes cambiar el tipo de los parametros o hacer un "convert" explicito.

...
where c1 = convert(money, @c1)

Es muy importante que el "convert" ocurra sobre el parametro y no sobre la
columna,
pues de lo contrario SQL Server no hara un uso adecuado de los indices, por
la columna en question,
en casos de estos existir.


AMB

"David Baez" wrote:

> De antemano muchas gracias.
>
> Es que las sentencias son de un proveedor y necesitábamos mas información
> que nos ayudara a darle una respuesta ya que el proveedor tenia la duda o
> quería saber por que en algunas ocasiones realiza por el CONVERT por el campo
> de comparación y en otras ocasiones realiza el CONVERT sobre la variable.
>
> Cabe de aclarar que son sentencias diferentes cuando el plan de ejecución
> realiza el CONVERT por el campo y el CONVERT por la variable.
>
> De todas formas ya le recomendamos al proveedor que modifique las variables
> de entrada y que sean del mismo tipo.
>
> Esta realiza el convert por el CAMPO
>
> exec sp_executesql N'SELECT
> COF_CONC,COF_CTEC,COF_CLIB,COF_CSEC,COF_CPRC,ITE_CONT,COF_CONT FROM
> IN_COFIN,IN_UBICA
> WHERE IN_COFIN.EMP_CODI = @P1
> AND IN_COFIN.INS_CONT = @P2
> AND IN_COFIN.BOD_CODI = @P3
> AND COF_CONC <> 0
> AND (((COF_CONC = 3 AND COF_INRE = ''T''))
> OR COF_CONC >= 0)
> AND COF_INRE <> ''J''
> AND IN_COFIN.EMP_CODI = IN_UBICA.EMP_CODI
> AND IN_COFIN.UBI_CONT = IN_UBICA.UBI_CONT
> AND IN_UBICA.TRU_CONT =@P4', N'@P1 money,@P2 money,@P3 money,@P4 money',
> $26.0000, $1.0000, $1.0000, $900.0000
>
> Esta realiza el convert por la variable
>
> exec sp_executesql N'SELECT
> PE_MDPED.EMP_CODI,PE_MDPED.MDP_CONT,PE_MDPED.PED_CONT,PE_MDPED.PRO_CONT,PE_MDPED.PRO_SUST,PE_MDPED.BOD_CONT,PE_MDPED.LIP_CONT,PE_MDPED.UNI_CODI,PE_MDPED.MDP_CANT,PE_MDPED.MDP_PRLI,
>
> PE_MDPED.MDP_VALO,PE_MDPED.MDP_PRMA,PE_MDPED.MDP_TIDE,PE_MDPED.MDP_PVDE,PE_MDPED.MDP_VADE,PE_MDPED.MDP_DEPP,PE_MDPED.MDP_DESC,PE_MDPED.MDP_CPIK,PE_MDPED.MDP_CCON,PE_MDPED.MDP_CDES,
>
> PE_MDPED.MDP_CFAC,PE_MDPED.MDP_PROM,PE_MDPED.MDP_BONI,PE_MDPED.MDP_ESTA,PE_MDPED.MDP_ORDC,
>
> PE_PEDIM.INS_CONT,PE_PEDIM.TOP_CODI,PE_PEDIM.ACT_CONT,PE_PEDIM.MON_CODI,FA_CLIEN.TCL_CODI,PE_PEDIM.UNN_CONT,PE_PEDIM.CLI_CODI,PE_PEDIM.DCL_CODD,PE_PEDIM.PED_FECH,PE_PEDIM.PED_FECH,IN_PRODU.PRO_CODI,IN_BODEG.BOD_CODI,IN_PRODU.PRO_CLNG,
>
> FA_CLIEN.CLI_PRIO,FA_CLIEN.CLI_SUIT,FA_CLIEN.CLI_MULT,FA_CLIEN.CLI_DIAL,FA_CLIEN.CLI_DVIG,FA_CLIEN.CLI_PLIN,FA_CLIEN.CLI_FPEC,FA_CLIEN.BOD_DEST,
> PE_PEDIM.PED_NUME,FA_CLIEN.CLI_BACK
> FROM PE_MDPED,PE_PEDIM,IN_PRODU,IN_BODEG,PE_CLASE,FA_CLIEN,PE_MTIPO
> WHERE PE_MDPED.EMP_CODI = PE_PEDIM.EMP_CODI
> AND PE_MDPED.PED_CONT = PE_PEDIM.PED_CONT
> AND PE_MDPED.EMP_CODI = IN_PRODU.EMP_CODI
> AND PE_MDPED.PRO_CONT = IN_PRODU.PRO_CONT
> AND PE_MDPED.EMP_CODI = IN_BODEG.EMP_CODI
> AND PE_MDPED.BOD_CONT = IN_BODEG.BOD_CONT
> AND PE_PEDIM.EMP_CODI = PE_CLASE.EMP_CODI
> AND PE_PEDIM.CLA_CONT = PE_CLASE.CLA_CONT
> AND PE_PEDIM.EMP_CODI = FA_CLIEN.EMP_CODI
> AND PE_PEDIM.CLI_CODI = FA_CLIEN.CLI_CODI
> AND PE_PEDIM.EMP_CODI = PE_MTIPO.EMP_CODI
> AND PE_PEDIM.MTI_CONT = PE_MTIPO.MTI_CONT
> AND PE_CLASE.CLA_PIKI = ''S''
> AND PE_MTIPO.MTI_SALD = ''S''
> AND PE_MDPED.MDP_BONI = ''N''
> AND PE_MDPED.PRO_CONT <> 0
> AND (PE_MDPED.MDP_ESTA = ''G'')
> AND PE_PEDIM.EMP_CODI = @P1
> AND PE_PEDIM.PED_NUME BETWEEN @P2 AND @P3
> ORDER BY FA_CLIEN.CLI_PRIO,PE_PEDIM.PED_CONT,PE_PEDIM.PED_FECH', N'@P1
> money,@P2 money,@P3 money', $94.0000, $8288.0000, $8288.0000
>
>
>
Respuesta Responder a este mensaje
#4 Alejandro Mesa
28/06/2006 - 17:16 | Informe spam
David,

El motor convertira el que tenga menor precedencia. Chequea los libros en
linea para mas info.

Data Type Precedence (Transact-SQL) - 2005
http://msdn2.microsoft.com/en-us/li...90309.aspx

Por ejemplo, si comparas smalldatetime con datetime, sql server convertira
implicitamente la variable smalldatetime (menor precedencia) hacia datetime.

use northwind
go

set showplan_text on
go

declare @d smalldatetime

set @d = '20060628'

select
*
from
dbo.orders
where
orderdate = @d
go

set showplan_text off
go

Result:

|--Bookmark Lookup(BOOKMARK:([Bmk1000]),
OBJECT:([northwind].[dbo].[Orders]))
|--Index Seek(OBJECT:([northwind].[dbo].[Orders].[OrderDate]),
SEEK:([Orders].[OrderDate]=Convert([@d])) ORDERED FORWARD)


Fijate que SQL Server convierte implicitamente la variable smalldatetime a
datetime porque
el tipo smalldatetime tiene menor precedencia que el tipo datetime, que es
el tipo de la columna [orderdate].

Ahora, si ejecutamos:

use northwind
go

set showplan_text on
go

declare @n numeric(10, 2)

set @n = 1250.50

select
*
from
dbo.[order details]
where
unitprice = @n
go

set showplan_text off
go

Result:

|--Clustered Index Scan(OBJECT:([northwind].[dbo].[Order
Details].[PK_Order_Details]), WHERE:(Convert([Order
Details].[UnitPrice])=[@n]))


Veras que SQL server convierte implicitamente el valor de la columna
[unitprice], que es de tipo money, hacia el tipo numeric.
Ya que "money" tiene menor precedencia que el tipo "numeric".


Para evitar converciones implicitas por parte de SQL Server, debemos
comparar tipos iguales, lo cual conseguimos
si usamos parametros y/o variables del mismo tipo de las columnas o hacemos
una conversion explicita.


declare @n numeric(10, 2)

set @n = 1250.50

select
*
from
dbo.[order details]
where
unitprice = cast(@n as money)
go

Result:

|--Clustered Index Scan(OBJECT:([northwind].[dbo].[Order
Details].[PK_Order_Details]), WHERE:([Order
Details].[UnitPrice]=Convert([@n])))



AMB


"David Baez" wrote:

Buenos Dias

Gracias alejandro de antemano, es que me equivoque y cree otra pregunta y
debia ser una respusta. La pregunta la puse ayer y tenia el mismo asunto.

Ya se le informo al proveedor que la solucion es que arreglen las consultas,
mi duda es como determina el motor en donde realizar el CONVERT si lo deber
realizar por el campo de comparacion o por la vaiable de entrada.



"Alejandro Mesa" escribió:

> David Baez,
>
> Cual es tu inquietud?
>
> Los parametros deben ser del mismo tipo que el de las columnas que
> participan en la expresion.
> Puedes cambiar el tipo de los parametros o hacer un "convert" explicito.
>
> ...
> where c1 = convert(money, @c1)
>
> Es muy importante que el "convert" ocurra sobre el parametro y no sobre la
> columna,
> pues de lo contrario SQL Server no hara un uso adecuado de los indices, por
> la columna en question,
> en casos de estos existir.
>
>
> AMB
>
> "David Baez" wrote:
>
> > De antemano muchas gracias.
> >
> > Es que las sentencias son de un proveedor y necesitábamos mas información
> > que nos ayudara a darle una respuesta ya que el proveedor tenia la duda o
> > quería saber por que en algunas ocasiones realiza por el CONVERT por el campo
> > de comparación y en otras ocasiones realiza el CONVERT sobre la variable.
> >
> > Cabe de aclarar que son sentencias diferentes cuando el plan de ejecución
> > realiza el CONVERT por el campo y el CONVERT por la variable.
> >
> > De todas formas ya le recomendamos al proveedor que modifique las variables
> > de entrada y que sean del mismo tipo.
> >
> > Esta realiza el convert por el CAMPO
> >
> > exec sp_executesql N'SELECT
> > COF_CONC,COF_CTEC,COF_CLIB,COF_CSEC,COF_CPRC,ITE_CONT,COF_CONT FROM
> > IN_COFIN,IN_UBICA
> > WHERE IN_COFIN.EMP_CODI = @P1
> > AND IN_COFIN.INS_CONT = @P2
> > AND IN_COFIN.BOD_CODI = @P3
> > AND COF_CONC <> 0
> > AND (((COF_CONC = 3 AND COF_INRE = ''T''))
> > OR COF_CONC >= 0)
> > AND COF_INRE <> ''J''
> > AND IN_COFIN.EMP_CODI = IN_UBICA.EMP_CODI
> > AND IN_COFIN.UBI_CONT = IN_UBICA.UBI_CONT
> > AND IN_UBICA.TRU_CONT =@P4', N'@P1 money,@P2 money,@P3 money,@P4 money',
> > $26.0000, $1.0000, $1.0000, $900.0000
> >
> > Esta realiza el convert por la variable
> >
> > exec sp_executesql N'SELECT
> > PE_MDPED.EMP_CODI,PE_MDPED.MDP_CONT,PE_MDPED.PED_CONT,PE_MDPED.PRO_CONT,PE_MDPED.PRO_SUST,PE_MDPED.BOD_CONT,PE_MDPED.LIP_CONT,PE_MDPED.UNI_CODI,PE_MDPED.MDP_CANT,PE_MDPED.MDP_PRLI,
> >
> > PE_MDPED.MDP_VALO,PE_MDPED.MDP_PRMA,PE_MDPED.MDP_TIDE,PE_MDPED.MDP_PVDE,PE_MDPED.MDP_VADE,PE_MDPED.MDP_DEPP,PE_MDPED.MDP_DESC,PE_MDPED.MDP_CPIK,PE_MDPED.MDP_CCON,PE_MDPED.MDP_CDES,
> >
> > PE_MDPED.MDP_CFAC,PE_MDPED.MDP_PROM,PE_MDPED.MDP_BONI,PE_MDPED.MDP_ESTA,PE_MDPED.MDP_ORDC,
> >
> > PE_PEDIM.INS_CONT,PE_PEDIM.TOP_CODI,PE_PEDIM.ACT_CONT,PE_PEDIM.MON_CODI,FA_CLIEN.TCL_CODI,PE_PEDIM.UNN_CONT,PE_PEDIM.CLI_CODI,PE_PEDIM.DCL_CODD,PE_PEDIM.PED_FECH,PE_PEDIM.PED_FECH,IN_PRODU.PRO_CODI,IN_BODEG.BOD_CODI,IN_PRODU.PRO_CLNG,
> >
> > FA_CLIEN.CLI_PRIO,FA_CLIEN.CLI_SUIT,FA_CLIEN.CLI_MULT,FA_CLIEN.CLI_DIAL,FA_CLIEN.CLI_DVIG,FA_CLIEN.CLI_PLIN,FA_CLIEN.CLI_FPEC,FA_CLIEN.BOD_DEST,
> > PE_PEDIM.PED_NUME,FA_CLIEN.CLI_BACK
> > FROM PE_MDPED,PE_PEDIM,IN_PRODU,IN_BODEG,PE_CLASE,FA_CLIEN,PE_MTIPO
> > WHERE PE_MDPED.EMP_CODI = PE_PEDIM.EMP_CODI
> > AND PE_MDPED.PED_CONT = PE_PEDIM.PED_CONT
> > AND PE_MDPED.EMP_CODI = IN_PRODU.EMP_CODI
> > AND PE_MDPED.PRO_CONT = IN_PRODU.PRO_CONT
> > AND PE_MDPED.EMP_CODI = IN_BODEG.EMP_CODI
> > AND PE_MDPED.BOD_CONT = IN_BODEG.BOD_CONT
> > AND PE_PEDIM.EMP_CODI = PE_CLASE.EMP_CODI
> > AND PE_PEDIM.CLA_CONT = PE_CLASE.CLA_CONT
> > AND PE_PEDIM.EMP_CODI = FA_CLIEN.EMP_CODI
> > AND PE_PEDIM.CLI_CODI = FA_CLIEN.CLI_CODI
> > AND PE_PEDIM.EMP_CODI = PE_MTIPO.EMP_CODI
> > AND PE_PEDIM.MTI_CONT = PE_MTIPO.MTI_CONT
> > AND PE_CLASE.CLA_PIKI = ''S''
> > AND PE_MTIPO.MTI_SALD = ''S''
> > AND PE_MDPED.MDP_BONI = ''N''
> > AND PE_MDPED.PRO_CONT <> 0
> > AND (PE_MDPED.MDP_ESTA = ''G'')
> > AND PE_PEDIM.EMP_CODI = @P1
> > AND PE_PEDIM.PED_NUME BETWEEN @P2 AND @P3
> > ORDER BY FA_CLIEN.CLI_PRIO,PE_PEDIM.PED_CONT,PE_PEDIM.PED_FECH', N'@P1
> > money,@P2 money,@P3 money', $94.0000, $8288.0000, $8288.0000
> >
> >
> >
Respuesta Responder a este mensaje
#5 David Baez
28/06/2006 - 17:38 | Informe spam
Buenos Dias


Gracias Alejandro este articulo me despejo todas las dudas.

Muchas Gracias.



"Alejandro Mesa" escribió:

David,

El motor convertira el que tenga menor precedencia. Chequea los libros en
linea para mas info.

Data Type Precedence (Transact-SQL) - 2005
http://msdn2.microsoft.com/en-us/li...90309.aspx

Por ejemplo, si comparas smalldatetime con datetime, sql server convertira
implicitamente la variable smalldatetime (menor precedencia) hacia datetime.

use northwind
go

set showplan_text on
go

declare @d smalldatetime

set @d = '20060628'

select
*
from
dbo.orders
where
orderdate = @d
go

set showplan_text off
go

Result:

|--Bookmark Lookup(BOOKMARK:([Bmk1000]),
OBJECT:([northwind].[dbo].[Orders]))
|--Index Seek(OBJECT:([northwind].[dbo].[Orders].[OrderDate]),
SEEK:([Orders].[OrderDate]=Convert([@d])) ORDERED FORWARD)


Fijate que SQL Server convierte implicitamente la variable smalldatetime a
datetime porque
el tipo smalldatetime tiene menor precedencia que el tipo datetime, que es
el tipo de la columna [orderdate].

Ahora, si ejecutamos:

use northwind
go

set showplan_text on
go

declare @n numeric(10, 2)

set @n = 1250.50

select
*
from
dbo.[order details]
where
unitprice = @n
go

set showplan_text off
go

Result:

|--Clustered Index Scan(OBJECT:([northwind].[dbo].[Order
Details].[PK_Order_Details]), WHERE:(Convert([Order
Details].[UnitPrice])=[@n]))


Veras que SQL server convierte implicitamente el valor de la columna
[unitprice], que es de tipo money, hacia el tipo numeric.
Ya que "money" tiene menor precedencia que el tipo "numeric".


Para evitar converciones implicitas por parte de SQL Server, debemos
comparar tipos iguales, lo cual conseguimos
si usamos parametros y/o variables del mismo tipo de las columnas o hacemos
una conversion explicita.


declare @n numeric(10, 2)

set @n = 1250.50

select
*
from
dbo.[order details]
where
unitprice = cast(@n as money)
go

Result:

|--Clustered Index Scan(OBJECT:([northwind].[dbo].[Order
Details].[PK_Order_Details]), WHERE:([Order
Details].[UnitPrice]=Convert([@n])))



AMB


"David Baez" wrote:

> Buenos Dias
>
> Gracias alejandro de antemano, es que me equivoque y cree otra pregunta y
> debia ser una respusta. La pregunta la puse ayer y tenia el mismo asunto.
>
> Ya se le informo al proveedor que la solucion es que arreglen las consultas,
> mi duda es como determina el motor en donde realizar el CONVERT si lo deber
> realizar por el campo de comparacion o por la vaiable de entrada.
>
>
>
> "Alejandro Mesa" escribió:
>
> > David Baez,
> >
> > Cual es tu inquietud?
> >
> > Los parametros deben ser del mismo tipo que el de las columnas que
> > participan en la expresion.
> > Puedes cambiar el tipo de los parametros o hacer un "convert" explicito.
> >
> > ...
> > where c1 = convert(money, @c1)
> >
> > Es muy importante que el "convert" ocurra sobre el parametro y no sobre la
> > columna,
> > pues de lo contrario SQL Server no hara un uso adecuado de los indices, por
> > la columna en question,
> > en casos de estos existir.
> >
> >
> > AMB
> >
> > "David Baez" wrote:
> >
> > > De antemano muchas gracias.
> > >
> > > Es que las sentencias son de un proveedor y necesitábamos mas información
> > > que nos ayudara a darle una respuesta ya que el proveedor tenia la duda o
> > > quería saber por que en algunas ocasiones realiza por el CONVERT por el campo
> > > de comparación y en otras ocasiones realiza el CONVERT sobre la variable.
> > >
> > > Cabe de aclarar que son sentencias diferentes cuando el plan de ejecución
> > > realiza el CONVERT por el campo y el CONVERT por la variable.
> > >
> > > De todas formas ya le recomendamos al proveedor que modifique las variables
> > > de entrada y que sean del mismo tipo.
> > >
> > > Esta realiza el convert por el CAMPO
> > >
> > > exec sp_executesql N'SELECT
> > > COF_CONC,COF_CTEC,COF_CLIB,COF_CSEC,COF_CPRC,ITE_CONT,COF_CONT FROM
> > > IN_COFIN,IN_UBICA
> > > WHERE IN_COFIN.EMP_CODI = @P1
> > > AND IN_COFIN.INS_CONT = @P2
> > > AND IN_COFIN.BOD_CODI = @P3
> > > AND COF_CONC <> 0
> > > AND (((COF_CONC = 3 AND COF_INRE = ''T''))
> > > OR COF_CONC >= 0)
> > > AND COF_INRE <> ''J''
> > > AND IN_COFIN.EMP_CODI = IN_UBICA.EMP_CODI
> > > AND IN_COFIN.UBI_CONT = IN_UBICA.UBI_CONT
> > > AND IN_UBICA.TRU_CONT =@P4', N'@P1 money,@P2 money,@P3 money,@P4 money',
> > > $26.0000, $1.0000, $1.0000, $900.0000
> > >
> > > Esta realiza el convert por la variable
> > >
> > > exec sp_executesql N'SELECT
> > > PE_MDPED.EMP_CODI,PE_MDPED.MDP_CONT,PE_MDPED.PED_CONT,PE_MDPED.PRO_CONT,PE_MDPED.PRO_SUST,PE_MDPED.BOD_CONT,PE_MDPED.LIP_CONT,PE_MDPED.UNI_CODI,PE_MDPED.MDP_CANT,PE_MDPED.MDP_PRLI,
> > >
> > > PE_MDPED.MDP_VALO,PE_MDPED.MDP_PRMA,PE_MDPED.MDP_TIDE,PE_MDPED.MDP_PVDE,PE_MDPED.MDP_VADE,PE_MDPED.MDP_DEPP,PE_MDPED.MDP_DESC,PE_MDPED.MDP_CPIK,PE_MDPED.MDP_CCON,PE_MDPED.MDP_CDES,
> > >
> > > PE_MDPED.MDP_CFAC,PE_MDPED.MDP_PROM,PE_MDPED.MDP_BONI,PE_MDPED.MDP_ESTA,PE_MDPED.MDP_ORDC,
> > >
> > > PE_PEDIM.INS_CONT,PE_PEDIM.TOP_CODI,PE_PEDIM.ACT_CONT,PE_PEDIM.MON_CODI,FA_CLIEN.TCL_CODI,PE_PEDIM.UNN_CONT,PE_PEDIM.CLI_CODI,PE_PEDIM.DCL_CODD,PE_PEDIM.PED_FECH,PE_PEDIM.PED_FECH,IN_PRODU.PRO_CODI,IN_BODEG.BOD_CODI,IN_PRODU.PRO_CLNG,
> > >
> > > FA_CLIEN.CLI_PRIO,FA_CLIEN.CLI_SUIT,FA_CLIEN.CLI_MULT,FA_CLIEN.CLI_DIAL,FA_CLIEN.CLI_DVIG,FA_CLIEN.CLI_PLIN,FA_CLIEN.CLI_FPEC,FA_CLIEN.BOD_DEST,
> > > PE_PEDIM.PED_NUME,FA_CLIEN.CLI_BACK
> > > FROM PE_MDPED,PE_PEDIM,IN_PRODU,IN_BODEG,PE_CLASE,FA_CLIEN,PE_MTIPO
> > > WHERE PE_MDPED.EMP_CODI = PE_PEDIM.EMP_CODI
> > > AND PE_MDPED.PED_CONT = PE_PEDIM.PED_CONT
> > > AND PE_MDPED.EMP_CODI = IN_PRODU.EMP_CODI
> > > AND PE_MDPED.PRO_CONT = IN_PRODU.PRO_CONT
> > > AND PE_MDPED.EMP_CODI = IN_BODEG.EMP_CODI
> > > AND PE_MDPED.BOD_CONT = IN_BODEG.BOD_CONT
> > > AND PE_PEDIM.EMP_CODI = PE_CLASE.EMP_CODI
> > > AND PE_PEDIM.CLA_CONT = PE_CLASE.CLA_CONT
> > > AND PE_PEDIM.EMP_CODI = FA_CLIEN.EMP_CODI
> > > AND PE_PEDIM.CLI_CODI = FA_CLIEN.CLI_CODI
> > > AND PE_PEDIM.EMP_CODI = PE_MTIPO.EMP_CODI
> > > AND PE_PEDIM.MTI_CONT = PE_MTIPO.MTI_CONT
> > > AND PE_CLASE.CLA_PIKI = ''S''
> > > AND PE_MTIPO.MTI_SALD = ''S''
> > > AND PE_MDPED.MDP_BONI = ''N''
> > > AND PE_MDPED.PRO_CONT <> 0
> > > AND (PE_MDPED.MDP_ESTA = ''G'')
> > > AND PE_PEDIM.EMP_CODI = @P1
> > > AND PE_PEDIM.PED_NUME BETWEEN @P2 AND @P3
> > > ORDER BY FA_CLIEN.CLI_PRIO,PE_PEDIM.PED_CONT,PE_PEDIM.PED_FECH', N'@P1
> > > money,@P2 money,@P3 money', $94.0000, $8288.0000, $8288.0000
> > >
> > >
> > >
email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida