when stored statement query example tsql

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

  1. 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 )
  2. Concatenación de cuerdas, como
    SELECT a + NULL -- Results in NULL
  3. 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