2009-03-11 15 views
6

Estoy tratando de implementar parámetros opcionales en un procedimiento almacenado que tengo, pero me encuentro con un problema. He aquí una consulta simplificada para ilustrar el tema:SQL Coalesce en la cláusula WHERE

SET ANSI_NULLS OFF 

DECLARE @MiddleName VARCHAR(20); 
SET @MiddleName = NULL; 

SELECT * FROM [Customer] 
WHERE [LastName] = 'Torres' 
AND [MiddleName] = COALESCE(@MiddleName, [MiddleName]) 

Cuando ejecuto esta consulta que necesito para obtener una fila de atrás, porque uno tiene Torres NULL en la columna de la [MiddleName]. Pero la consulta devuelve cero filas. El uso de IFNULL() produce el mismo resultado. Al investigar COALESCE, tuve la impresión de que se devolvería NULL si todas las expresiones son NULL. Como no soy un experto en SQL, supongo que me falta algo, pero qué es ...

Gracias de antemano por cualquier ayuda.

+0

Estoy tratando de interpretar lo que está diciendo correctamente. Creo que te refieres a lo siguiente: cómo se combina para decir todas las filas si nulo, de lo contrario solo las filas coinciden. Si ese es el caso, haría algo como COALESCE (@MiddleName, '') = '' OR @ MiddleName = [MiddleName] en la cláusula where. – geoffrobinson

Respuesta

12

El problema es que en sql, "WHERE Null = Null" nunca devolverá ninguna fila ya que Null no se iguala.

que tiene que hacer

SELECT * FROM [Customer] 
WHERE [LastName] = 'Torres' 
AND (@MiddleName IS NULL OR [MiddleName] = @MiddleName) 
+2

Otra alternativa es: COALESCE ([MiddleName], '') = COALESCE (@MiddleName, [MiddleName], '') –

+0

utilizando "@var IS NULL" devuelve una constante que el optimizador puede usar para acortar la condición. Lo sugerido por Joel requeriría '' ser comparado con cada MiddleName. En el ejemplo de David, el MiddleName no necesita ser comparado ya que el optimizador sabe VERDADERO O es siempre cierto. – MatBailie

2

¿Estás intentando hacer esto?

SELECT * FROM [Customer] 
WHERE [LastName] = 'Torres' 
AND ([MiddleName] = @MiddleName OR @MiddleName IS NULL) 

Según tengo entendido, parece que sí.

+0

le faltan algunos corchetes: AND ([MiddleName] = @MiddleName OR [MiddleName] IS NULL) – TrevorD

+0

hmm, también podría ser necesario poner el [Middlename] es NULL primero – TrevorD

+0

[Middlename] es NULL primero? ¿por qué? – gcores

2

Sus rendimientos COALESCENULL cuando el parámetro @MiddleName y la columna de MiddleName son tanto NULL, pero la prueba será evaluada como falsa porque a NULL does not equal any other NULL.

Para solucionar esto, usted debe probar explícitamente el parámetro @MiddleName de nulidad:

SELECT * 
FROM [Customer] 
WHERE [LastName] = 'Torres' 
    AND (@MiddleName IS NULL OR [MiddleName] = @MiddleName) 
+0

de manera equivocada, intenta hacer que si @MiddleName es NULL, se ignore de manera efectiva, lo que hace que el parámetro sea pseudo opcional – MatBailie

3

Usted afirma que busca la consulta para devolver la fila donde el MiddleName campo es nulo. Desafortunadamente (NULL = NULL) no devuelve verdadero, devuelve NULL.

Usted necesita algo así como ...

SELECT * FROM [Customer] 
WHERE [LastName] = 'Torres' 
AND ([MiddleName] = @MiddleName OR @MiddleName IS NULL)