Order by - Dónde está el error?

13/10/2008 - 14:58 por Don Juan | Informe spam
Hola a todos.
Este es el código:
Declare @OrderBy nvarchar(50)
Set @OrderBy = 'Cust_Country'

Select
Cust_id, Cust_Serv_Rep, Cust_Type, Cust_Country,
Cust_Name
FROM Customer
ORDER BY
CASE
WHEN @OrderBy = 'Cust_id' THEN Cust_id
WHEN @OrderBy = 'Cust_Serv_Rep' THEN Cust_Serv_Rep
WHEN @OrderBy = 'Cust_Type' THEN Cust_Type
WHEN @OrderBy = 'Cust_country' THEN Cust_Country
WHEN @OrderBy = 'Cust_Name' THEN Cust_Name
END
Este es el mensaje de error que tengo al querer hacer un order by
ustilizando una variable @OrderBy

Msg 245, Level 16, State 1, Line 5
Syntax error converting the nvarchar value 'Germany' to a column of data
type int.
He revisado las columnas muchas veces y los tipos de datos están correctos
el
Cust_id - INT,
Cust_Serv_Rep - nvarchar(50),
Cust_Type - nchar(20),
Cust_Country - nvarchar(50),
Cust_Name - nvarchar(250)
Cuando hago el Order by Cust_Country no tengo ningún problema los campos son
ordenados.
Cuando uso el CASE y ordeno una columna de tipo entero como el Cust_ID no
tengo problema, el problema es cuando quiero ordenar un tipo nvarchar o
char.

Si alguien puede darme una mano le agradeceré mucho, de lo contrario lo que
ando buscando es una forma de ordenar cuando el SQL recive una variable la
cual será el campo de orden.

1000 gracias!

Preguntas similare

Leer las respuestas

#1 Juan Diego Bueno
13/10/2008 - 15:16 | Informe spam
Hola Juan:

On 13 oct, 14:58, "Don Juan" wrote:
Hola  a todos.
Este es el código:
Declare @OrderBy nvarchar(50)
Set @OrderBy = 'Cust_Country'

Select
    Cust_id,     Cust_Serv_Rep,       Cust_Type,    Cust_Country,
Cust_Name
FROM   Customer
ORDER BY
    CASE
        WHEN @OrderBy = 'Cust_id'  THEN Cust_id
        WHEN @OrderBy = 'Cust_Serv_Rep' THEN Cust_Serv_Rep
        WHEN @OrderBy = 'Cust_Type'  THEN Cust_Type
        WHEN @OrderBy = 'Cust_country' THEN Cust_Country
        WHEN @OrderBy = 'Cust_Name'  THEN Cust_Name
    END
Este es el mensaje de error que tengo al querer hacer un order by
ustilizando una variable @OrderBy

Msg 245, Level 16, State 1, Line 5
Syntax error converting the nvarchar value 'Germany' to a column of data
type int.
He revisado las columnas muchas veces y los tipos de datos están correctos
el
    Cust_id  - INT,
    Cust_Serv_Rep  - nvarchar(50),
    Cust_Type - nchar(20),
    Cust_Country - nvarchar(50),
    Cust_Name - nvarchar(250)
Cuando hago el Order by Cust_Country no tengo ningún problema los campos son
ordenados.
Cuando uso el CASE y ordeno una columna de tipo entero como el Cust_ID no
tengo problema, el problema es cuando quiero ordenar un tipo nvarchar o
char.

Si alguien puede darme una mano le agradeceré mucho, de lo contrario lo que
ando buscando es una forma de ordenar cuando el SQL recive una variable la
cual será el campo de orden.



Creo que tu problema reside en que usas el parámetro para un campo de
la query, cuando (que yo sepa) sólo puedes usarlo para valores.

Mecanismos para solucionar esto:

- Hacer el case en T-SQL dentro de una función de usuario que te
devuelva un tipo tabla con el resultado de la query. Eso sí, vas a
tener que hacer por cada case una query prácticamente idéntica excepto
en la parte del order by.
- Usar SQL Dinámico: Sería crear un procedimiento almacenado que
devuelva también ese resultado y generar la query dinámicamente.
Generarías una query dinámica que sustituyera el valor de @orderby por
el nombre del campo que desees. Para ello, revisa la sintaxis de
sp_executesql. Si te propongo el SP para ésto es porque las funciones
de usuario no permiten la ejecución dinámica de SQL. Un inconveniente
que puedes encontrar en esto es que pudiera haber inyección de código
SQL. Una forma simple de impedir esto es evaluar si @orderby es un
nombre de columna válido, haciendo una query sobre las vistas del
sistema (sys.columns o information_schema.columns) comprobando que
efectivamente, ese nombre de columna existe.

Un saludo
Respuesta Responder a este mensaje
#2 Don Juan
13/10/2008 - 16:55 | Informe spam
Gracias...
Intenté esto y funciona:
ORDER BY
CASE WHEN @OrderBy = 'Cust_id' THEN Cust_id END DESC,
CASE WHEN @OrderBy = 'Cust_Serv_Rep' THEN Cust_Serv_Rep END DESC,
CASE WHEN @OrderBy = 'Cust_Type' THEN Cust_Type END DESC,
CASE WHEN @OrderBy = 'Cust_country' THEN Cust_Country END DESC,
CASE WHEN @OrderBy = 'Cust_Name' THEN Cust_Name END DESC

Ahora el problema que tendo es que DESC y ASC también deben estar en una
variable @Direction
y una línea así no funciona:
@Direction = 'DESC'
CASE WHEN @OrderBy = 'Cust_country' THEN Cust_Country END @Direction,

Me da error... alguna sugerencia?


"Don Juan" wrote in message
news:
Hola a todos.
Este es el código:
Declare @OrderBy nvarchar(50)
Set @OrderBy = 'Cust_Country'

Select
Cust_id, Cust_Serv_Rep, Cust_Type, Cust_Country, Cust_Name
FROM Customer
ORDER BY
CASE
WHEN @OrderBy = 'Cust_id' THEN Cust_id
WHEN @OrderBy = 'Cust_Serv_Rep' THEN Cust_Serv_Rep
WHEN @OrderBy = 'Cust_Type' THEN Cust_Type
WHEN @OrderBy = 'Cust_country' THEN Cust_Country
WHEN @OrderBy = 'Cust_Name' THEN Cust_Name
END
Este es el mensaje de error que tengo al querer hacer un order by
ustilizando una variable @OrderBy

Msg 245, Level 16, State 1, Line 5
Syntax error converting the nvarchar value 'Germany' to a column of data
type int.
He revisado las columnas muchas veces y los tipos de datos están correctos
el
Cust_id - INT,
Cust_Serv_Rep - nvarchar(50),
Cust_Type - nchar(20),
Cust_Country - nvarchar(50),
Cust_Name - nvarchar(250)
Cuando hago el Order by Cust_Country no tengo ningún problema los campos
son ordenados.
Cuando uso el CASE y ordeno una columna de tipo entero como el Cust_ID no
tengo problema, el problema es cuando quiero ordenar un tipo nvarchar o
char.

Si alguien puede darme una mano le agradeceré mucho, de lo contrario lo
que ando buscando es una forma de ordenar cuando el SQL recive una
variable la cual será el campo de orden.

1000 gracias!

Respuesta Responder a este mensaje
#3 Ele
13/10/2008 - 17:22 | Informe spam
Hola
haz una condicion if como son 2 valores posibles solo vas a repetir 2 veces
el mismo codigo
y lo pones si es Asc o Desc
ejemplo:
If @Direction = 'ASC'
ORDER BY
CASE WHEN @OrderBy = 'Cust_id' THEN Cust_id END ASC,
CASE WHEN @OrderBy = 'Cust_Serv_Rep' THEN Cust_Serv_Rep END ASC,
CASE WHEN @OrderBy = 'Cust_Type' THEN Cust_Type END ASC,
CASE WHEN @OrderBy = 'Cust_country' THEN Cust_Country END ASC,
CASE WHEN @OrderBy = 'Cust_Name' THEN Cust_Name END ASC
Else
ORDER BY
CASE WHEN @OrderBy = 'Cust_id' THEN Cust_id END DESC,
CASE WHEN @OrderBy = 'Cust_Serv_Rep' THEN Cust_Serv_Rep END DESC,
CASE WHEN @OrderBy = 'Cust_Type' THEN Cust_Type END DESC,
CASE WHEN @OrderBy = 'Cust_country' THEN Cust_Country END DESC,
CASE WHEN @OrderBy = 'Cust_Name' THEN Cust_Name END DESC




"Don Juan" escribió en el mensaje
news:
Gracias...
Intenté esto y funciona:
ORDER BY
CASE WHEN @OrderBy = 'Cust_id' THEN Cust_id END DESC,
CASE WHEN @OrderBy = 'Cust_Serv_Rep' THEN Cust_Serv_Rep END DESC,
CASE WHEN @OrderBy = 'Cust_Type' THEN Cust_Type END DESC,
CASE WHEN @OrderBy = 'Cust_country' THEN Cust_Country END DESC,
CASE WHEN @OrderBy = 'Cust_Name' THEN Cust_Name END DESC

Ahora el problema que tendo es que DESC y ASC también deben estar en una
variable @Direction
y una línea así no funciona:
@Direction = 'DESC'
CASE WHEN @OrderBy = 'Cust_country' THEN Cust_Country END @Direction,

Me da error... alguna sugerencia?


"Don Juan" wrote in message
news:
Hola a todos.
Este es el código:
Declare @OrderBy nvarchar(50)
Set @OrderBy = 'Cust_Country'

Select
Cust_id, Cust_Serv_Rep, Cust_Type, Cust_Country,
Cust_Name
FROM Customer
ORDER BY
CASE
WHEN @OrderBy = 'Cust_id' THEN Cust_id
WHEN @OrderBy = 'Cust_Serv_Rep' THEN Cust_Serv_Rep
WHEN @OrderBy = 'Cust_Type' THEN Cust_Type
WHEN @OrderBy = 'Cust_country' THEN Cust_Country
WHEN @OrderBy = 'Cust_Name' THEN Cust_Name
END
Este es el mensaje de error que tengo al querer hacer un order by
ustilizando una variable @OrderBy

Msg 245, Level 16, State 1, Line 5
Syntax error converting the nvarchar value 'Germany' to a column of data
type int.
He revisado las columnas muchas veces y los tipos de datos están
correctos el
Cust_id - INT,
Cust_Serv_Rep - nvarchar(50),
Cust_Type - nchar(20),
Cust_Country - nvarchar(50),
Cust_Name - nvarchar(250)
Cuando hago el Order by Cust_Country no tengo ningún problema los campos
son ordenados.
Cuando uso el CASE y ordeno una columna de tipo entero como el Cust_ID no
tengo problema, el problema es cuando quiero ordenar un tipo nvarchar o
char.

Si alguien puede darme una mano le agradeceré mucho, de lo contrario lo
que ando buscando es una forma de ordenar cuando el SQL recive una
variable la cual será el campo de orden.

1000 gracias!




Respuesta Responder a este mensaje
#4 Alejandro Mesa
14/10/2008 - 01:32 | Informe spam
Don Juan,

El problema esta cuando los tipos de datos devueltos por las partes THEN no
son compatibles. El tipo de dato que devuelve la funcion case, es el tipo de
mayor precedencia entre todos los tipos que participan en las partes THEN y
ELSE, por lo que cuando se devuelve un valor que no puede ser convertido
explicitamente hacia el tipo de mayor precedencia, entonces tienes un error.

Ejemplo:

DECLARE @i INT

SET @i = 2

select
CASE @i
when 1 then 1
when 2 then 'error'
else 1.00 end
go

Aqui tenemos tres tipos, entero, numerico y caracter. El tipo numerico es el
de mayor precedencia, por lo tanto si ejecutas este script con @i = 1, no
habra problema porque SQL Server convertira el valor 1 a numerico, pero si
ejecutas el script para @i = 2 entonces dara error porque el valor 'error' no
se puede convertir a numerico.

Ahora que sabes como funciona la funcion case, sabras que puedes arreglar el
problema convirtiendo explicitamente los valores para estos sean compatibles.
En tu caso, deberas convertir el valor entero a caracter para que este no sea
mas el de mayor precedencia.

ORDER BY
CASE
WHEN @OrderBy = 'Cust_id' THEN Cust_id
WHEN @OrderBy = 'Cust_Serv_Rep' THEN Cust_Serv_Rep
WHEN @OrderBy = 'Cust_Type' THEN Cust_Type
WHEN @OrderBy = 'Cust_country' THEN Cust_Country
WHEN @OrderBy = 'Cust_Name' THEN Cust_Name
END



ORDER BY
CASE
WHEN @OrderBy = 'Cust_id' THEN cast(Cust_id as varchar(15))
WHEN @OrderBy = 'Cust_Serv_Rep' THEN Cust_Serv_Rep
WHEN @OrderBy = 'Cust_Type' THEN Cust_Type
WHEN @OrderBy = 'Cust_country' THEN Cust_Country
WHEN @OrderBy = 'Cust_Name' THEN Cust_Name
END


Cuidado al ordenar alfabeticamente, puesto que a veces resulta dificil de
comprender, como en el ejemplo que sigue.

SELECT *
FROM (SELECT '1A' AS c1 UNION ALL SELECT '12A' UNION ALL SELECT '13B') AS t
ORDER BY 1
GO

Otra forma seria convertiendo todos los tipos a sql_variant, pero igual,
mezclar diferentes tipos y ordenarlos alfabeticamente puede dar resultados no
esperados.

DECLARE @i INT

SET @i = 2

SELECT CASE @i
WHEN 1 THEN CAST(1 AS SQL_VARIANT)
WHEN 2 THEN CAST('error' AS SQL_VARIANT)
ELSE CAST(1.00 AS SQL_VARIANT)
END
go

Como ultimo, puedes utilizar sql dinamico. Solo ten en cuenta la posibilidad
de injeccion de codigo t-sql.


AMB


"Don Juan" wrote:

Hola a todos.
Este es el cdigo:
Declare @OrderBy nvarchar(50)
Set @OrderBy = 'Cust_Country'

Select
Cust_id, Cust_Serv_Rep, Cust_Type, Cust_Country,
Cust_Name
FROM Customer
ORDER BY
CASE
WHEN @OrderBy = 'Cust_id' THEN Cust_id
WHEN @OrderBy = 'Cust_Serv_Rep' THEN Cust_Serv_Rep
WHEN @OrderBy = 'Cust_Type' THEN Cust_Type
WHEN @OrderBy = 'Cust_country' THEN Cust_Country
WHEN @OrderBy = 'Cust_Name' THEN Cust_Name
END
Este es el mensaje de error que tengo al querer hacer un order by
ustilizando una variable @OrderBy

Msg 245, Level 16, State 1, Line 5
Syntax error converting the nvarchar value 'Germany' to a column of data
type int.
He revisado las columnas muchas veces y los tipos de datos estn correctos
el
Cust_id - INT,
Cust_Serv_Rep - nvarchar(50),
Cust_Type - nchar(20),
Cust_Country - nvarchar(50),
Cust_Name - nvarchar(250)
Cuando hago el Order by Cust_Country no tengo ningn problema los campos son
ordenados.
Cuando uso el CASE y ordeno una columna de tipo entero como el Cust_ID no
tengo problema, el problema es cuando quiero ordenar un tipo nvarchar o
char.

Si alguien puede darme una mano le agradecer mucho, de lo contrario lo que
ando buscando es una forma de ordenar cuando el SQL recive una variable la
cual ser el campo de orden.

1000 gracias!

Respuesta Responder a este mensaje
#5 Don Juan
14/10/2008 - 08:48 | Informe spam
Muy bien explicado.
Muchas gracias Alejandro

"Alejandro Mesa" wrote in message
news:
Don Juan,

El problema esta cuando los tipos de datos devueltos por las partes THEN
no
son compatibles. El tipo de dato que devuelve la funcion case, es el tipo
de
mayor precedencia entre todos los tipos que participan en las partes THEN
y
ELSE, por lo que cuando se devuelve un valor que no puede ser convertido
explicitamente hacia el tipo de mayor precedencia, entonces tienes un
error.

Ejemplo:

DECLARE @i INT

SET @i = 2

select
CASE @i
when 1 then 1
when 2 then 'error'
else 1.00 end
go

Aqui tenemos tres tipos, entero, numerico y caracter. El tipo numerico es
el
de mayor precedencia, por lo tanto si ejecutas este script con @i = 1, no
habra problema porque SQL Server convertira el valor 1 a numerico, pero si
ejecutas el script para @i = 2 entonces dara error porque el valor 'error'
no
se puede convertir a numerico.

Ahora que sabes como funciona la funcion case, sabras que puedes arreglar
el
problema convirtiendo explicitamente los valores para estos sean
compatibles.
En tu caso, deberas convertir el valor entero a caracter para que este no
sea
mas el de mayor precedencia.

ORDER BY
CASE
WHEN @OrderBy = 'Cust_id' THEN Cust_id
WHEN @OrderBy = 'Cust_Serv_Rep' THEN Cust_Serv_Rep
WHEN @OrderBy = 'Cust_Type' THEN Cust_Type
WHEN @OrderBy = 'Cust_country' THEN Cust_Country
WHEN @OrderBy = 'Cust_Name' THEN Cust_Name
END



ORDER BY
CASE
WHEN @OrderBy = 'Cust_id' THEN cast(Cust_id as varchar(15))
WHEN @OrderBy = 'Cust_Serv_Rep' THEN Cust_Serv_Rep
WHEN @OrderBy = 'Cust_Type' THEN Cust_Type
WHEN @OrderBy = 'Cust_country' THEN Cust_Country
WHEN @OrderBy = 'Cust_Name' THEN Cust_Name
END


Cuidado al ordenar alfabeticamente, puesto que a veces resulta dificil de
comprender, como en el ejemplo que sigue.

SELECT *
FROM (SELECT '1A' AS c1 UNION ALL SELECT '12A' UNION ALL SELECT '13B') AS
t
ORDER BY 1
GO

Otra forma seria convertiendo todos los tipos a sql_variant, pero igual,
mezclar diferentes tipos y ordenarlos alfabeticamente puede dar resultados
no
esperados.

DECLARE @i INT

SET @i = 2

SELECT CASE @i
WHEN 1 THEN CAST(1 AS SQL_VARIANT)
WHEN 2 THEN CAST('error' AS SQL_VARIANT)
ELSE CAST(1.00 AS SQL_VARIANT)
END
go

Como ultimo, puedes utilizar sql dinamico. Solo ten en cuenta la
posibilidad
de injeccion de codigo t-sql.


AMB


"Don Juan" wrote:

Hola a todos.
Este es el cdigo:
Declare @OrderBy nvarchar(50)
Set @OrderBy = 'Cust_Country'

Select
Cust_id, Cust_Serv_Rep, Cust_Type, Cust_Country,
Cust_Name
FROM Customer
ORDER BY
CASE
WHEN @OrderBy = 'Cust_id' THEN Cust_id
WHEN @OrderBy = 'Cust_Serv_Rep' THEN Cust_Serv_Rep
WHEN @OrderBy = 'Cust_Type' THEN Cust_Type
WHEN @OrderBy = 'Cust_country' THEN Cust_Country
WHEN @OrderBy = 'Cust_Name' THEN Cust_Name
END
Este es el mensaje de error que tengo al querer hacer un order by
ustilizando una variable @OrderBy

Msg 245, Level 16, State 1, Line 5
Syntax error converting the nvarchar value 'Germany' to a column of data
type int.
He revisado las columnas muchas veces y los tipos de datos estn correctos
el
Cust_id - INT,
Cust_Serv_Rep - nvarchar(50),
Cust_Type - nchar(20),
Cust_Country - nvarchar(50),
Cust_Name - nvarchar(250)
Cuando hago el Order by Cust_Country no tengo ningn problema los campos
son
ordenados.
Cuando uso el CASE y ordeno una columna de tipo entero como el Cust_ID no
tengo problema, el problema es cuando quiero ordenar un tipo nvarchar o
char.

Si alguien puede darme una mano le agradecer mucho, de lo contrario lo
que
ando buscando es una forma de ordenar cuando el SQL recive una variable
la
cual ser el campo de orden.

1000 gracias!

email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida