2012-06-21 12 views
6

Supponiamo che x sia una variabile che ha un valore diverso da null, ad esempio 4, ad esempio. Cosa dovrebbe restituire la seguente espressione?Nella maggior parte delle implementazioni SQL, al contrario dei linguaggi di programmazione standard, perché x! = Null restituisce true?

x != null 

In quasi ogni linguaggio di programmazione che abbia mai lavorato con (C#, Javascript, PHP, Python), questa espressione, o un'espressione equivalente in quella lingua, valuta a true.

Le implementazioni SQL, d'altra parte, sembrano gestirlo in modo completamente diverso. Se uno o entrambi gli operandi dell'operatore di disuguaglianza sono NULL, verrà restituito NULL o False. Questo è fondamentalmente l'opposto del comportamento che la maggior parte dei linguaggi di programmazione utilizza, ed è estremamente non intuitivo per me.

Perché il comportamento in SQL è simile? Che cos'è la logica di database relazionale che fa sì che null si comporti in modo così diverso rispetto alla programmazione generale?

+0

fa x! = Null funziona in molte implementazioni SQL? Ho sempre usato x non è nullo. –

+3

Perché 'NULL' è sconosciuto. Potrebbe essere 4. Questo è sicuramente un dupe. –

+1

Un modo in cui ho sentito spiegare è che "NULL è uno stato di essere, non un valore". – bluevector

risposta

7

Il nulla nella maggior parte dei linguaggi di programmazione è considerato "conosciuto", mentre NULL in SQL è considerato "sconosciuto".

  • Quindi X == null confronta X con un valore noto e il risultato è noto (vero o falso).
  • Ma X = NULL confronta X con un valore sconosciuto e il risultato è sconosciuto (ad esempio NULL, di nuovo). Di conseguenza, abbiamo bisogno di un operatore speciale IS [NOT] NULL per testarlo.

Sto indovinando almeno parte della motivazione per tali NULL sarebbe il comportamento delle chiavi esterne. Quando un endpoint secondario di una chiave esterna è NULL, non dovrebbe corrispondere a nessun genitore, anche se il genitore è NULL (che è possibile se genitore è UNICO invece che chiave primaria). Sfortunatamente, questo porta molto più gotchas di quello che risolve e personalmente penso che SQL avrebbe dovuto seguire il percorso del "noto" nullo ed evitare del tutto il business delle scimmie.

Anche E. F. Codd, inventore o modello relazionale, ha successivamente indicato che il NULL tradizionale non è ottimale. Ma per ragioni storiche, siamo praticamente bloccati da esso.

1

bene nei motori sql di solito non si utilizza l'operatore "=" ma "IS", che quindi rende più intuitivo.

SELECT 4 IS NULL FROM dual; 
> 0 


SELECT 4 IS NOT NULL FROM dual; 
> 1 

NULL non rappresenta il puntatore nullo, non è affatto lo stesso concetto. sql NULL è un Non conosco il valore flag, non è un flag "non c'è puntatore". Non dovresti confrontarli, non dovrebbero essere usati allo stesso modo. Questo è abbastanza intuitivo hai ragione, avrebbero dovuto chiamarlo in modo diverso.

+0

Sono consapevole che l'operatore IS (NOT) NULL esiste, questo in realtà non risponde alla mia domanda; Sto chiedendo sul perché '! =' Funziona come fa, non sui modi per aggirare il suo strano comportamento –

+0

sì, hai ragione ma non dovresti usare null in questo modo ... – Sebas

6

la ragione è che il concetto di uguaglianza non si applica a null. non è logicamente vero dire che questo null fa o non uguaglia questo altro nullo.

quindi, tutto ciò va bene per un motivo teorico, ma per motivi di praticità, perché sql non consente che tu dica (x! = Null)?

beh, il motivo è perché a volte si desidera gestire null in modo diverso. se dico (colonnaA = colonnaB) per esempio, dovrebbe restituire true se entrambe le colonne sono nulle? se dico (colonnaA! = ColonnaB) - dovrebbe dare lo stesso risultato quando la colonna A è "a" e la colonna B è nulla, e quando la colonna A è "a" e la colonna B è "b"?

le persone che hanno reso sql hanno deciso che la distinzione era importante e quindi l'hanno scritta per trattare i 2 casi in modo diverso.

pagina di Wikipedia su questo ha un interessante resoconto abbastanza decente - http://en.wikipedia.org/wiki/Null_%28SQL%29

+0

Perché è questo speciale per i database? Perché le persone non hanno fatto lo stesso comportamento di confronto con i tipi nullable nei linguaggi di programmazione standard? –

+1

beh, se dovessi indovinare ... SQL è più radicato nei concetti di programmazione in stile funzionale. i linguaggi di programmazione standard sono generalmente imperativi. in SQL stai essenzialmente descrivendo il problema e lasciando che il tuo server db capisca come risolvere il problema. dal lato imperativo stai normalmente dicendo al programma come risolvere il tuo problema passo dopo passo. tipicamente le persone che sono in logica funzionale si preoccupano più profondamente del significato sottostante delle affermazioni funzionali rispetto a un approccio imperativo dove assumiamo che possiamo dirgli come risolvere il problema. – bkr

+0

in breve: da una prospettiva funzionale, è più importante essere in grado di descrivere con precisione il tuo problema. – bkr

0

In SQL, NULL significa "un valore sconosciuto".

Se dici x! = NULL stai dicendo "è il valore di x non uguale a un valore sconosciuto". Bene, dato che non sappiamo quale sia il valore sconosciuto, non sappiamo se x sia uguale o no. Quindi la risposta è "non lo so".

Allo stesso modo:

x = NULL OR 1=2 -- Unknown. 1=2 is not true, but we don't know about x=NULL 
x = NULL OR 1=1 -- True. We know that at least 1=1 is true, so the OR is fulfulled regardless. 
x = NULL AND 1=1 -- Unknown. We want them both to be true to fulful the AND 
x = NULL AND 1=2 -- False. We know 1=2 is false, so the AND is not fulfilled regardless. 

anche

-- Neither statement will select rows where x is null 
select x from T where x = 1 
select x from T where x != 1 

L'unico modo per controllare un null è quello di chiedere specificatamente "è vero che non sappiamo quale sia il valore di x è". Questo ha una risposta affermativa o negativa e utilizza la parola chiave IS.

Se si desidera che i null vengano considerati come zero o un altro valore, è possibile utilizzare la funzione COALESCE o ISNULL.

COALESCE(NULL, 1) -- 1 
COALESCE(NULL, NULL, 1) -- Also 1 
COALESCE(x, y, z, 0) -- x, unless it is null, then y, unless it is null, then z, unless it is null in which case 0. 
+0

In SQL, null * non * rappresenta veramente un valore sconosciuto. Se così fosse, X = X valuterà correttamente a TRUE (in matematica, logica e realtà un valore sconosciuto è sicuramente uguale a se stesso!) Lo standard SQL non definisce il significato di null, semplicemente definisce la sua sintassi e (comportamento strano, inconsistente, non matematico). L'idea che null in qualche modo "significa" sconosciuto è solo un'ipotesi imprecisa e spesso pericolosa fatta da alcuni professionisti di SQL. – sqlvogel

+0

L'interrogante stava cercando un modo per capire NULL, non la definizione standard SQL. – Ben

+0

"in matematica, logica e realtà un valore sconosciuto è sicuramente uguale a se stesso". No. Un valore sconosciuto non è necessariamente uguale a un altro valore sconosciuto. Non conosco la data di nascita di Joel Spolsky né conosco la data di nascita di Raymond Chen. Ciò non significa che siano uguali. – Ben

Problemi correlati