Auto-valore NULL in una tabella


13

Sono sempre perplesso riguardo un comportamento misterioso di t-sql, come il seguente

-- 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 

Non si tratta di come recuperare tutte le righe in una tabella e nemmeno di evitare l'uso di ANSI_NULLS.

Voglio solo sollecitare alcune intuizioni sul perché t-sql si comporti in questo modo.

Risposte:


13

Questo è un comportamento sorprendente, ma dalla pagina MSDN SET ANSI_NULLS, possiamo almeno sapere che è il comportamento previsto. Un motivo in più per non usare mai ANSI_NULLS OFF:

SET ANSI_NULLSinfluisce su un confronto solo se uno degli operandi del confronto è una variabile che è NULLo un letterale NULL. Se entrambi i lati del confronto sono colonne o espressioni composte, l'impostazione non influisce sul confronto.


8

Anche se potrebbe non essere cristallino dalla documentazione di msdn, credo che troverai quanto segue vero

"SET ANSI_NULLS ON influenza un confronto solo se uno degli operandi del confronto è una variabile NULL o un NULL letterale. Se entrambi i lati del confronto sono colonne o espressioni composte, l'impostazione non influisce sul confronto."

Vedi questo /programming/2866714/how-does-ansi-nulls-work-in-tsql


Grazie Scott e ypercube, entrambe le risposte sono importanti per questo comportamento, quindi ho votato entrambe le risposte.
jyao,

Ypercube è stato il primo :)
Scott Hodgin il

4

Robert Sheldon nel seguente post del 2015 discute i comportamenti NULL e perché a volte (ma non sempre) falliscono

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

Descrive 13 errori NULL che un programmatore può facilmente inciampare.

Errore n. 1: non sapere cosa significa NULL

Spiegazione: NULL è un valore non valido, un valore inesistente. Non è zero. Non è una stringa vuota. Un valore non può essere uguale a NULL. Nessun due valori NULL sono uguali .

Questo è il problema di base, ma assicurati di leggere gli altri errori.

Sì, le versioni precedenti (credo prima di SQL Server 7) si comportavano in modo diverso, più simile a ciò che si desidera.

Tuttavia, se cerchi il problema su Stack Overflow e Stack Exchange troverai molti thread lunghi che ne discutono.


3
Una volta ho letto il post collegato di Robert Sheldon, ma non ha (IMHO) alcuna teoria o prova che spieghi il comportamento del mio esempio.
jyao,

1
"Nessun due valori NULL sono uguali." OK, ma anche le persone che sanno che si aspetterebbero il contrario quando ansi null è disattivato. Soprattutto perché WHERE NULL = NULLrende vero quando l'impostazione è di.
ypercubeᵀᴹ

1

Per aggiungere alla discussione, la definizione di NULL dello standard SQL92 può essere interpretata in modo ambiguo. Ecco un buon riassunto della gestione e dell'interpretazione NULL da vari DBMS per gentile concessione di sqlite.org.

INFORMATIVA : Ricordo di aver letto dell '"ambiguità" di SQL92 da una versione precedente (come 6-8 anni fa) della pagina sqlite.org collegata sopra, ma quella pagina è stata aggiornata da allora.

La risposta di RLF sopra ha una buona citazione, ma se non sono d'accordo con Robert Sheldon è solo perché considero "qualcosa che non esiste" (cioè un NULL ) come filosoficamente e inglese-semanticamente equivalente a " qualcos'altro che non esiste ". Se devo capire la logica di Sheldon, allora si potrebbe dichiarare che la definizione di NULL è anche NULL. (Se non esiste, come possiamo definirlo? Creepy, eh?)

Vedo una variazione del birrificio Paradox di Russell ( e un mal di testa). : - \

Ma ancora una volta, questa è una discussione sulla semantica della lingua inglese ( NON SQL) e il dibattito filosofico appartiene qui . :-)


PS Sono nuovo qui in questa comunità SE; se questo è stato discusso prima della nausea , allora mi scuso.
pr1268,

1
Dov'è esattamente l'ambiguità nello standard?
ypercubeᵀᴹ

@ ypercubeᵀᴹ: credo che l'ambiguità risiedesse nel tentativo di "adattare" un 3VL in un booleano. I join di tabella con confronti NULL possono essere interpretati in diversi modi.
pr1268,

Concordo sull'incoerenza ma non sull'ambiguità.
ypercubeᵀᴹ

1
@ ypercubeᵀᴹ: Abbastanza giusto ... Stavo solo citando ciò che diceva una versione precedente della pagina sqlite.org che ho linkato sopra ("SQL92 è ambiguo per quanto riguarda la gestione e l'interpretazione NULL" o qualcosa di molto simile). Ma non intendo discutere. Forse la pagina sqlite.org era essa stessa fuorviante e / o totalmente errata. Il che probabilmente spiega perché è stato aggiornato.
pr1268,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.