2012-01-06 15 views
6

¿Es posible usar un operador de comparación en una función CONVERT o CAST?¿Por qué la comparación no funciona en CONVERTIR?

Tengo una declaración que tiene este aspecto:

SELECT 
    ... 
    CASE field 
     WHEN 'Y' THEN 1 # If Y then True 
     ELSE 0   # Anything else is False 
    END 
    ... 
FROM ... 

Algo similar ocurre durante algunos campos, por lo que le gustaría cambiar a una versión más corta:

SELECT 
    ... 
    CONVERT(BIT, field = 'Y') 
    ... 
FROM ... 

pero MSSQL está dando un error Incorrect syntax near '='.

Mi interpretación de la ayuda es que debería funcionar:

  • CONVERT (data_type [ (length) ] , expression [ , style ])
  • expression: expression { binary_operator } expression
  • binary_operator: es un operador que define la forma en dos expresiones se combinan para producir un solo resultado. binary_operator puede ser un operador aritmético, el operador de asignación (=), un operador bit a bit, un operador de comparación, un operador lógico, el operador de concatenación de cadenas (+) o un operador unario.
  • comparison operator: (= | > | < | >= | <= | <> | != | !< | !>)

Me corrieron algunas pruebas y tiene los siguientes resultados:

SELECT CONVERT(BIT, 0)  // 0 
SELECT CONVERT(BIT, 1)  // 1 
SELECT CONVERT(BIT, 1+2)  // 1 
SELECT CONVERT(BIT, 1=2)  // Error 
SELECT CONVERT(BIT, (1=2)) // Error 
SELECT CONVERT(BIT, (1)=(2)) // Error 
+0

campo = 'Y' es una tarea, no una expresión. En cualquier caso, un tipo de datos de bit solo puede contener un 0 o 1. La sentencia CASE es correcta ya que asigna 1 cuando field = 'Y'. –

Respuesta

4

creo que está mal interpretando la documentación para CONVERT. No hay nada en la documentación para CONVERT que indique que manejará una expresión que hace uso de los operadores de comparación, solo que acepta una expresión. Resulta que CONVERT no maneja todas las expresiones SQL válidas. Por lo menos, no puede manejar los resultados de una expresión que utiliza un operador de comparación.

Si comprueba la documentación para Operators, verá que los operadores de comparación (que es lo que quiere = a ser, en este caso) devolver un tipo de datos Boolean, y se utilizan en las cláusulas WHERE y el control de - declaraciones de flujo. A partir de la documentación para operadores:

El resultado de un operador de comparación tiene el tipo de datos Boolean, que tiene tres valores: VERDADERO, FALSO, y desconocido. Las expresiones que devuelven un tipo de datos Boolean se conocen como expresiones booleanas.

A diferencia de otros tipos de datos SQL Server, un tipo de datos Boolean no se puede especifica como el tipo de datos de una columna de tabla o variable, y no pueden ser devueltos en un conjunto de resultados.

...

expresiones con tipos de datos booleanos se utilizan en la cláusula WHERE para filtrar las filas que cumplen los requisitos para las condiciones de búsqueda y en instrucciones del lenguaje de control de flujo, tales como IF y WHILE .. .

Eso ayuda a explicar por qué SQL como SQL SELECT 1=2 es válido, porque crearía un conjunto de resultados con un tipo de datos Boolean, que la documentación dice que no está permitido.Eso también explica por qué la construcción CASE WHEN es necesaria, porque puede evaluar los operadores de comparación y devolver un único valor de un tipo de datos que SQL Server puede devolver en un conjunto de resultados.

Por otra parte, si nos fijamos en la documentación de CONVERT, verá que Boolean no es compatible, ya sea en CAST o CONVERT (ver la tabla hacia el centro de la página, no hay ningún tipo de datos Boolean allí).

Para sus propósitos, creo que está atascado usando CASE WHEN. Si ayuda se puede escribir en una sola línea:

CASE WHEN field = 'Y' THEN 1 ELSE 0 END 

Como alternativa, puede crear una UDF para manejar la expresión CASE (algo así como dbo.func_DoCase(field, 'Y', 1, 0)), pero personalmente me acaba de pegarse con CASE WHEN.

+0

+1 Sospecho que tienes razón. Iba a decir exactamente esto, pero tú me ganaste. – Wiseguy

+0

@Wiseguy: Gracias. Sé que el SQL 'SELECT CONVERT (BIT, 1 = 2)' no es válido, pero trata de descubrir exactamente por qué el uso de la documentación es un poco difícil. – rsbarro

+0

Sí, pensaría que la documentación lo señalaría claramente y que el error arrojado sería más útil. La "sintaxis incorrecta" suena más como un simple error tipográfico en lugar de "bueno, estás ensamblando las piezas correctamente, pero por razones no obvias, no siento la necesidad de explicar que no pertenecen a esta ubicación en particular". – Wiseguy

Cuestiones relacionadas