T-SQL CASE Clause: How to specify WHEN NULL
eu escrevi uma declaração T-SQL semelhante a esta (a original parece diferente, mas eu quero dar um exemplo fácil aqui):
SELECT first_name +
CASE last_name WHEN null THEN 'Max' ELSE 'Peter' END AS Name
FROM dbo.person
esta Declaração não tem quaisquer erros de sintaxe, mas a cláusula case-clause sempre escolhe a outra parte-também se o last_name for nulo. Mas Porquê?
O Que Eu quero fazer é unir o primeiro nome e o último nome, mas se o último nome for nulo o nome inteiro torna-se nulo:
SELECT first_name +
CASE last_name WHEN null THEN '' ELSE ' ' + last_name END AS Name
FROM dbo.person
Sabes onde está o problema?
14 answers
CASE WHEN last_name IS NULL THEN '' ELSE ' '+last_name END
A parte quando é comparada com==, mas você não pode realmente comparar com NULL. Tenta
CASE WHEN last_name is NULL THEN ... ELSE .. END
Em vez disso ou carvão:
COALESCE(' '+last_name,'')
(''+last_name is NULL when last_name is NULL, so it should return " in that case)
Dada a sua pergunta, também pode fazer isto:
SELECT first_name + ' ' + ISNULL(last_name, '') AS Name FROM dbo.person
O problema é que null não é considerado igual a si mesmo, portanto a cláusula nunca corresponde.
Você precisa verificar se null explicitamente:
SELECT CASE WHEN last_name is NULL THEN first_name ELSE first_name + ' ' + last_name
CASE last_name WHEN null THEN '' ELSE ' '+last_name
Depois do "quando", há uma verificação da igualdade, que deve ser verdadeira ou falsa.
Se uma ou ambas as partes de uma comparação for nula, o resultado da comparação será desconhecido, que é tratado como falso em uma estrutura de caso. Ver: https://www.xaprb.com/blog/2006/05/18/why-null-never-compares-false-to-anything-in-sql/
Para evitar isto, o Coalesce é o melhor. forma.Tenta:
SELECT first_name + ISNULL(' '+last_name, '') AS Name FROM dbo.person
Isto adiciona o espaço ao último nome, se for nulo, o espaço inteiro+último nome vai para NULL e só obtém um primeiro nome, caso contrário obtém um firts+espaço+último nome.
Isto irá funcionar desde que a configuração por omissão para a concatenação com cadeias nulas seja definida:
SET CONCAT_NULL_YIELDS_NULL ON
Isto não deve ser uma preocupação, uma vez que o modo OFF
está a desaparecer nas versões futuras do servidor SQl
A questão é que NULL não é considerado igual a nada mesmo não a si mesmo, mas a parte estranha é que também não é igual a si mesmo.
Considere as seguintes declarações (que é BTW ilegal no servidor SQL T-SQL, mas é válido no My-SQL, no entanto isto é o que ANSI define para null, e pode ser verificado mesmo no servidor SQL usando declarações de caso etc.)
SELECT NULL = NULL -- Results in NULL
SELECT NULL <> NULL -- Results in NULL
Isto tem muitas implicações, por exemplo em
- extratos de casos, nos quais qualquer valor nulo irá sempre usar a outra cláusula, a menos que você use explicitamente a condição de quando é nulo (Não a condição de
WHEN NULL
- concatenação de cordas, como
SELECT a + NULL -- Results in NULL
- em um onde dentro ou onde não em cláusula, como se você quiser resultados corretos certifique-se na sub-consulta correlacionada para filtrar qualquer nulo valores.
Pode-se anular este comportamento no servidor SQL especificando {[[4]}, no entanto este é Não recomendado e não deve ser feito como pode causar muitos problemas, simplesmente porque o desvio do padrão.
(como nota lateral, no My-SQL existe uma opção para usar um operador especial <=>
para comparação nula.)
Em comparação, em linguagens de programação gerais null é tratado é um valor regular e é igual a si mesmo, no entanto o é o valor NAN que é também não é igual a si mesmo, mas pelo menos retorna 'false' ao compará-lo a si mesmo, (e ao verificar não é igual a linguagens de programação diferentes têm implementações diferentes).
Note No entanto que nas línguas de base (isto é, VB, etc.) não existe palavra-chave' null 'E em vez disso se usa a palavra-chave 'nada', que não pode ser usada em comparação direta e em vez disso é preciso usar' IS ' como em SQL, no entanto, é de fato igual a si mesmo (ao usar comparações indiretas).
CASE
WHEN last_name IS null THEN ''
ELSE ' ' + last_name
END
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
Quando ficas frustrado a tentar isto:
CASE WHEN last_name IS NULL THEN '' ELSE ' '+last_name END
Tenta este em vez disso.:
CASE LEN(ISNULL(last_Name,''))
WHEN 0 THEN ''
ELSE ' ' + last_name
END AS newlastName
LEN(ISNULL(last_Name,''))
mede o número de caracteres nessa coluna, que será zero quer esteja vazia, ou nula, portanto WHEN 0 THEN
irá avaliar para true e devolver o " como esperado.
Incluí este teste para o servidor sql 2008 e 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
Pode usar a função IsNull
select
isnull(rtrim(ltrim([FirstName]))+' ','') +
isnull(rtrim(ltrim([SecondName]))+' ','') +
isnull(rtrim(ltrim([Surname]))+' ','') +
isnull(rtrim(ltrim([SecondSurname])),'')
from TableDat
Se uma coluna for nula, obteria um char vazio
Compatível com o Microsoft SQL Server 2008 +
Utilize a função CONCAT disponível no servidor SQL 2012 em diante.
SELECT CONCAT([FirstName], ' , ' , [LastName]) FROM YOURTABLE
CASE
WHEN LEN(CAST(field_value AS VARCHAR(MAX))) = 0 THEN
DO THIS
END AS field
NULL não é igual a nada. A declaração de caso está basicamente dizendo Quando o valor = nulo .. nunca vai bater.
Existem também vários procedimentos armazenados no sistema que são escritos incorretamente com a sua sintaxe. Ver sp_addpullsubscription_agent e sp_who2.
Gostaria de saber como notificar a Microsoft desses erros como eu não sou capaz de mudar o sistema armazenado procs.