Auto-comparação de valor NULL em uma tabela


13

Estou sempre intrigado com algum comportamento misterioso do t-sql, como o seguinte

-- Create table t and insert values.  
use tempdb
CREATE TABLE dbo.t (a INT NULL);  
-- insert 3 values
INSERT INTO dbo.t values (NULL),(0),(1);  
GO  
set ansi_nulls off -- purposely turn off, so we can allow NULL comparison, such as null = null
go
-- expect 3 rows returned but only 2 returned (without null value row)
select * from dbo.t where a = a 

Não se trata de como recuperar todas as linhas de uma tabela e também de evitar o uso de ANSI_NULLS.

Eu só quero solicitar algumas idéias sobre por que o t-sql se comporta dessa maneira.

Respostas:


13

Esse é um comportamento surpreendente, mas, na página do MSDN SET ANSI_NULLS, podemos pelo menos saber que esse é o comportamento esperado. Mais um motivo para nunca usar ANSI_NULLS OFF:

SET ANSI_NULLSafeta uma comparação apenas se um dos operandos da comparação for uma variável que é NULLou uma literal NULL. Se os dois lados da comparação forem colunas ou expressões compostas, a configuração não afetará a comparação.


8

Embora possa não estar claro na documentação do msdn, acredito que você encontrará o seguinte

"SET ANSI_NULLS ON afeta uma comparação apenas se um dos operandos da comparação for uma variável NULL ou literal NULL. Se os dois lados da comparação forem colunas ou expressões compostas, a configuração não afetará a comparação."

Consulte este /programming/2866714/how-does-ansi-nulls-work-in-tsql


Obrigado Scott e ypercube, as duas respostas estão nos pontos corretos para esse comportamento, por isso eu votei nas duas respostas.
— precisa saber é

Ypercube foi o primeiro :)
— Scott Hodgin

4

Robert Sheldon no post a seguir de 2015 discute comportamentos NULL e por que às vezes (mas nem sempre) falham

https://www.simple-talk.com/sql/t-sql-programming/how-to-get-nulls-horribly-wrong-in-sql-server/

Ele descreve 13 falhas nulas que um programador pode facilmente tropeçar.

Falha nº 1: sem saber o que significa NULL

Explicação: NULL é um valor não existente, um valor inexistente. Não é zero. Não é uma string vazia. Um valor não pode ser igual a NULL. Não há dois valores NULL iguais .

Esse é o problema básico, mas não deixe de ler sobre as outras falhas.

Sim, as versões anteriores (acredito que antes do SQL Server 7) se comportaram de maneira diferente, mais parecidas com o que você deseja.

No entanto, se você procurar o problema no Stack Overflow e no Stack Exchange, encontrará muitos threads longos discutindo os problemas.


3
Uma vez, li o post vinculado de Robert Sheldon, mas ele (IMHO) não tem nenhuma teoria ou evidência que explique o comportamento do meu exemplo.
— jyao

1
"Não existem dois valores NULL iguais." OK, mas mesmo as pessoas que sabem que esperariam o contrário quando ansi nulls estiver desativado. Especialmente porque o WHERE NULL = NULLrendimento é verdadeiro quando a configuração é de.
— precisa saber é o seguinte

1

Para adicionar à discussão, a definição de NULL do padrão SQL92 pode ser interpretada de forma ambígua. Aqui está um bom resumo do manuseio e interpretação de NULL de vários DBMS, cortesia de sqlite.org.

DIVULGAÇÃO : Eu meio que lembro de ler sobre a "ambiguidade" do SQL92 a partir de uma versão mais antiga (há 6 a 8 anos) da página sqlite.org vinculada acima, mas essa página foi atualizada desde então.

A resposta de RLF acima tem uma boa citação, mas se eu não concordar com Robert Sheldon é só porque eu considero "algo que não existe" (ou seja, um NULL ) para ser filosoficamente e Inglês-language-semanticamente equivalente a "alguma coisa outra coisa que não existe " Se eu quiser entender a lógica de Sheldon, pode-se declarar que a definição de NULL também é NULL. (Se não existe, como podemos defini-lo? Assustador, hein?)

Eu vejo uma variação da produção de Russell's Paradox ( e uma dor de cabeça). : - \

Mas, novamente, esta é uma discussão sobre semântica no idioma inglês ( NOT SQL) e o debate sobre filosofia pertence aqui . :-)


PS Eu sou novo aqui nesta comunidade SE; se isso já foi discutido ad nauseum , peço desculpas.
— pr1268

1
Onde exatamente está a ambiguidade no padrão?
— precisa saber é o seguinte

@ ypercubeᵀᴹ: Eu acredito que a ambiguidade está na tentativa de "encaixar" uma 3VL em um booleano. As junções de tabela com comparações NULL podem ser interpretadas de várias maneiras diferentes.
— pr1268

Eu concordaria em inconsistência, mas não em ambiguidade.
— precisa saber é o seguinte

1
@ ypercubeᵀᴹ: É justo ... Eu estava apenas citando o que uma versão mais antiga da página sqlite.org vinculei acima disse ("SQL92 é ambíguo no que diz respeito à manipulação e interpretação de NULL" ou algo muito semelhante). Mas não pretendo discutir. Talvez a página sqlite.org tenha sido enganosa e / ou totalmente incorreta. O que provavelmente explica por que foi atualizado.
— precisa saber é
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.