tsql - stored - null in case statement sql
Cláusula CASE de T-SQL: cómo especificar cuándo NULL (14)
Dada tu consulta también puedes hacer esto:
SELECT first_name + '' '' + ISNULL(last_name, '''') AS Name FROM dbo.person
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 del caso siempre elige la parte ELSE, también si el último nombre 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?
El problema es que NULL no se considera igual a nada, ni siquiera a sí mismo, pero la parte extraña es que tampoco es igual a sí mismo.
Considere las siguientes declaraciones (que es BTW ilegal en SQL Server T-SQL pero es válida en My-SQL, sin embargo, esto es lo que ANSI define como nulo, y puede verificarse incluso en SQL Server usando declaraciones de casos, etc.)
SELECT NULL = NULL -- Results in NULL
SELECT NULL <> NULL -- Results in NULL
Así que no hay una respuesta verdadera / falsa a la pregunta, sino que la respuesta también es nula.
Esto tiene muchas implicaciones, por ejemplo en
- Sentencias CASE, en las que cualquier valor nulo siempre usará la cláusula ELSE a menos que use explícitamente la condición WHEN IS NULL ( NO la condición
WHEN NULL
) - Concatenación de cuerdas, como
SELECT a + NULL -- Results in NULL
- En una cláusula WHERE IN o WHERE NOT IN, como si quisiera obtener resultados correctos, asegúrese de que en la subconsulta correlacionada se filtre cualquier valor nulo.
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 comparación nula).
En comparación, en general, los lenguajes de programación null se trata es 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 con él mismo (y Cuando la comprobación de no es igual a diferentes lenguajes de programación tiene diferentes implementaciones).
Sin embargo, tenga en cuenta que en los idiomas 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 cambio, se debe usar ''IS'' como en SQL. sin embargo, de hecho es igual a sí mismo (cuando se usan comparaciones indirectas).
El problema es que null no se considera igual a sí mismo, por lo tanto, la cláusula nunca coincide.
Necesitas verificar nulo explícitamente:
SELECT CASE WHEN last_name is NULL THEN first_name ELSE first_name + '' '' + last_name
Hay muchas soluciones, pero ninguna cubre por qué la declaración original no funciona.
CASE last_name WHEN null THEN '''' ELSE '' ''+last_name
Después del cuándo, hay un control de igualdad, que debe ser verdadero o falso.
Si una o ambas partes de una comparación son nulas, el resultado de la comparación será DESCONOCIDO, que se trata como falso en la estructura de un caso. Consulte: https://www.xaprb.com/blog/2006/05/18/why-null-never-compares-false-to-anything-in-sql/
Para evitar esto, Coalesce es la mejor manera.
Intenté lanzar una cadena y probar una cadena de longitud cero y funcionó.
CASE
WHEN LEN(CAST(field_value AS VARCHAR(MAX))) = 0 THEN
DO THIS
END AS field
Jason captó un error, así que esto funciona ...
¿Alguien puede confirmar las otras versiones de la plataforma?
Servidor SQL:
SELECT
CASE LEN(ISNULL(last_name,''''))
WHEN 0 THEN ''''
ELSE '' '' + last_name
END AS newlastName
MySQL:
SELECT
CASE LENGTH(IFNULL(last_name,''''))
WHEN 0 THEN ''''
ELSE '' '' + last_name
END AS newlastName
Oráculo:
SELECT
CASE LENGTH(NVL(last_name,''''))
WHEN 0 THEN ''''
ELSE '' '' + last_name
END AS newlastName
La parte WHEN se compara con ==, pero realmente no se puede comparar con NULL. Tratar
CASE WHEN last_name is NULL THEN ... ELSE .. END
En su lugar o COALESCE:
COALESCE('' ''+last_name,'''')
('''' + last_name es NULL cuando last_name es NULL, por lo que debería devolver '''' en ese caso)
NULL no es igual a nada. La declaración del caso básicamente dice que cuando el valor = NULL ... nunca llegará.
También hay varios procedimientos almacenados del sistema que están escritos incorrectamente con su sintaxis. Ver sp_addpullsubscription_agent y sp_who2.
Ojalá supiera notificar esos errores a Microsoft, ya que no puedo cambiar los procedimientos almacenados en el sistema.
Puedes usar la función IsNull
select
isnull(rtrim(ltrim([FirstName]))+'' '','''') +
isnull(rtrim(ltrim([SecondName]))+'' '','''') +
isnull(rtrim(ltrim([Surname]))+'' '','''') +
isnull(rtrim(ltrim([SecondSurname])),'''')
from TableDat
si una columna es nula obtendrías un char vacío
Compatible con Microsoft SQL Server 2008+
Utilice la función CONCAT disponible en SQL Server 2012 en adelante.
SELECT CONCAT([FirstName], '' , '' , [LastName]) FROM YOURTABLE
tratar:
SELECT first_name + ISNULL('' ''+last_name, '''') AS Name FROM dbo.person
Esto agrega el espacio al apellido, si es nulo, todo el espacio + apellido pasa a NULL y solo obtiene un nombre; de lo contrario, obtiene un primer + espacio + apellido.
esto funcionará siempre que se establezca la configuración predeterminada para la concatenación con cadenas nulas:
SET CONCAT_NULL_YIELDS_NULL ON
Esto no debería ser una preocupación, ya que el modo de OFF
( OFF
) desaparecerá en futuras versiones de SQl Server.
Cuando te frustras intentando esto:
CASE WHEN last_name IS NULL THEN '''' ELSE '' ''+last_name END
Prueba este en su lugar:
CASE LEN(ISNULL(last_Name,''''))
WHEN 0 THEN ''''
ELSE '' '' + last_name
END AS newlastName
LEN(ISNULL(last_Name,''''))
mide el número de caracteres en esa columna, que será cero si está vacío, o NULL, por lo tanto, WHEN 0 THEN
se evaluará como verdadero y devolverá el '''' como se esperaba.
Espero que esta sea una alternativa útil.
He incluido este caso de prueba para el servidor SQL 2008 y superior:
DECLARE @last_Name varchar(50) = NULL
SELECT
CASE LEN(ISNULL(@last_Name,''''))
WHEN 0 THEN ''''
ELSE ''A '' + @last_name
END AS newlastName
SET @last_Name = ''LastName''
SELECT
CASE LEN(ISNULL(@last_Name,''''))
WHEN 0 THEN ''''
ELSE ''A '' + @last_name
END AS newlastName
CASE
WHEN last_name IS null THEN ''''
ELSE '' '' + last_name
END
CASE WHEN last_name IS NULL THEN '''' ELSE '' ''+last_name END