Escribí una declaración T-SQL similar a esta (la original se ve diferente pero quiero dar un ejemplo fácil aquí):
SELECT first_name +
CASE last_name WHEN null THEN 'Max' ELSE 'Peter' END AS Name
FROM dbo.person
Esta declaración no tiene ningún error de sintaxis, pero la cláusula case siempre elige la parte ELSE, también si el last_name es nulo. ¿Pero por qué?
Lo que quiero hacer es unir first_name y last_name, pero si last_name es nulo, el nombre completo se vuelve nulo:
SELECT first_name +
CASE last_name WHEN null THEN '' ELSE ' ' + last_name END AS Name
FROM dbo.person
¿Sabes dónde está el problema?
COALESCE
básicamente se traduce internamente enCASE
. El problema con CASE es quelast_name
se evalúa dos veces y puede provocar otros efectos secundarios; consulte este excelente artículo . Para resolver lo que se pidió, preferiría ir con loISNULL(' '+ last_name, '')
mencionado en el comentario a continuación.La parte WHEN se compara con ==, pero realmente no se puede comparar con NULL. Tratar
en cambio o COALESCE:
('' + last_name es NULL cuando last_name es NULL, por lo que debería volver '' en ese caso)
fuente
Hay muchas soluciones, pero ninguna cubre por qué la declaración original no funciona.
Después del cuándo, hay una comprobación de igualdad, que debería ser verdadera o falsa.
Si una o ambas partes de una comparación es nula, el resultado de la comparación será DESCONOCIDO, que se trata como falso en una estructura de caso. Ver: https://www.xaprb.com/blog/2006/05/18/why-null-never-compares-false-to-anything-in-sql/
Para evitar esto, la fusión es la mejor manera.
fuente
Dada su consulta, también puede hacer esto:
fuente
ISNULL(' '+ last_name, '')
para evitar el espacio redundante.El problema es que nulo no se considera igual a sí mismo, por lo tanto, la cláusula nunca coincide.
Debe verificar nulo explícitamente:
fuente
tratar:
Esto agrega el espacio al apellido, si es nulo, todo el espacio + apellido va a NULL y solo obtienes un nombre, de lo contrario obtienes un primer nombre + espacio + apellido.
esto funcionará mientras se establezca la configuración predeterminada para la concatenación con cadenas nulas:
Esto no debería ser una preocupación ya que el
OFF
modo desaparecerá en futuras versiones de SQL Serverfuente
El problema es que NULL no se considera igual a nada, ni siquiera a sí mismo, pero lo extraño es que tampoco es igual a sí mismo.
Considere las siguientes declaraciones (que por cierto es ilegal en SQL Server T-SQL pero es válido en My-SQL, sin embargo, esto es lo que ANSI define para nulo, y se puede verificar incluso en SQL Server mediante el uso de declaraciones de casos, etc.)
SELECT NULL = NULL -- Results in NULL
SELECT NULL <> NULL -- Results in NULL
Por lo tanto, no hay una respuesta verdadera / falsa a la pregunta, sino que la respuesta también es nula.
Esto tiene muchas implicaciones, por ejemplo en
WHEN NULL
condición )SELECT a + NULL -- Results in NULL
Se puede anular este comportamiento en SQL Server especificando
SET ANSI_NULLS OFF
, sin embargo, esto NO se recomienda y no debe hacerse, ya que puede causar muchos problemas, simplemente debido a la desviación del estándar.(Como nota al margen, en My-SQL hay una opción para usar un operador especial
<=>
para la comparación nula).En comparación, en los lenguajes de programación generales, nulo se trata como un valor regular y es igual a sí mismo, sin embargo, es el valor NAN que tampoco es igual a sí mismo, pero al menos devuelve 'falso' al compararlo consigo mismo (y cuando verifica que no sea igual, diferentes lenguajes de programación tienen implementaciones diferentes).
Sin embargo, tenga en cuenta que en los lenguajes básicos (es decir, VB, etc.) no hay una palabra clave 'nula' y en su lugar se usa la palabra clave 'Nada', que no se puede usar en comparación directa y en su lugar se debe usar 'IS' como en SQL, sin embargo, de hecho es igual a sí mismo (cuando se usan comparaciones indirectas).
fuente
fuente
Cuando te sientas frustrado intentando esto:
Prueba este en su lugar:
LEN(ISNULL(last_Name,''))
mide el número de caracteres en esa columna, que será cero si está vacío o NULL, porWHEN 0 THEN
lo tanto, se evaluará como verdadero y devolverá el '' como se esperaba.Espero que esta sea una alternativa útil.
He incluido este caso de prueba para SQL Server 2008 y superior:
fuente
Jason detectó un error, así que esto funciona ...
¿Alguien puede confirmar las otras versiones de la plataforma?
Servidor SQL:
MySQL:
Oráculo:
fuente
Puedes usar la función IsNull
si una columna es nula obtendría un carácter vacío
Compatible con Microsoft SQL Server 2008+
fuente
Use la función CONCAT disponible en SQL Server 2012 en adelante.
fuente
Intenté lanzar una cadena y probar una cadena de longitud cero y funcionó.
fuente
NULL no es igual a nada. La declaración del caso básicamente dice cuando el valor = NULL ... nunca golpeará.
También hay varios procedimientos almacenados del sistema que están escritos incorrectamente con su sintaxis. Consulte sp_addpullsubscription_agent y sp_who2.
Ojalá supiera cómo notificar a Microsoft sobre esos errores, ya que no puedo cambiar los procesos almacenados del sistema.
fuente