2

Bitte sehen diese beiden Aussagen: (!)Operator NICHT invertieren nicht das Ergebnis eines NULL Vergleich

select 'true' where (1 = NULL) ; 

select 'true' where not (1 = NULL) ; 

Beide von ihnen leer zurückkehren!

Das bedeutet also, dass die Ausdrücke (1=NULL) und not (1=NULL) beide falsch ausgeben! Aber wie kann das sein? Ich dachte, der Operator NOT(expression) wird das Ergebnis des Ausdrucks invertieren?

Nach Microsoft: "Vergleichen von NULL mit einem Nicht-NULL-Wert führt immer zu FALSE."

OK, aber das würde bedeuten, dass der Operator NOT das Ergebnis invertieren muss. Aber warum macht es das nicht?

https://msdn.microsoft.com/en-us/library/ms188074.aspx

EDIT: Ich stellte den falschen Artikel. Mein Zitat ist oben aus diesem Artikel: https://msdn.microsoft.com/en-us/library/ms175118.aspx

Es scheint dieser Artikel einen Fehler hat, wie in den Antworten und Kommentaren unten angegeben.

+5

Sie können nicht 'verwenden =' zu nulls zu vergleichen. Sie müssen 'IS NULL' verwenden. Jeder Vergleich mit '=' mit NULL ergibt 'NULL' und das Gegenteil von' NULL' ist ebenfalls 'NULL'. Es ist dasselbe wie zu fragen: "Ist die Farbe deines Raumschiffs weiß" oder "Ist die Farbe deines Raumschiffs nicht weiß?". Sie können keines von beiden beantworten, weil Sie kein Raumschiff –

+1

@a_horse_with_no_name haben, aber dann ist die Microsoft-Dokumentation falsch. – askolotl

+3

Der Artikel, den Sie verknüpft haben, besagt, dass "ein Operator, der einen oder zwei NULL-Ausdrücke hat, UNKNOWN zurückgibt". Daher wird Ihr '1 = NULL'-Vergleich immer UNBEKANNT zurückgeben, nicht WAHR oder FALSCH. UNBEKANNT kehrt zu UNBEKANNT zurück. Daher bekommst du in beiden Fällen nichts zurück. – strickt01

Antwort

2

So implementiert T-SQL, was als Three-Valued Logic bekannt ist. Das bedeutet, dass jeder im T-SQL-Code vorhandene logische Ausdruck TRUE, FALSE ODER NULL auswerten kann. Jetzt bietet Ihnen SQL Server 2 Optionen zur Behandlung logischer Ausdrücke mit NULLs mit dem Befehl SET ANSI_NULL. Das Standardverhalten von SQL Server (SET ANSI_NULL ON) ist, dass jeder logische Vergleich mit NULLNULL zurückgibt. Die folgenden Ausdrücke

NULL = NULL; 
1 = NULL; 
1 <> NULL; 

werden alle zu NULL auswerten. Wenn Sie aus irgendeinem Grund möchten, dass der logische Ausdruck true oder false zurückgibt, auch wenn sie NULL-Werte enthalten, müssen Sie ANSI_NULL ausschalten, aber das ist nicht ratsam.

Kleine bearbeiten: Der einzige Fall, dass ein logischer Ausdruck NULL einschließlich auf etwas anderes als NULL bewerten wird, ist die folgende:

(NULL) OR (TRUE) = TRUE 

So ist die folgende T-SQL-Code

SET ANSI_NULLS ON; 
GO 
IF ((NULL=NULL) OR (1=1)) 
    PRINT 'True'; 
GO 

wird tatsächlich drucken True.

+0

Tatsächlich erklärt die dreiwertige Logik alles. Danke fürs Schreiben, ich werde dich aufrüsten, sobald ich das Recht dazu habe (brauche 15 Punkte) – askolotl

+1

Kein Problem! Im Allgemeinen ist das Vorhandensein und die Verwendung von 'NULL' ein sehr diskutiertes und interessantes Thema in relationalen Datenbanken. Wenn Sie wirklich in Datenbank-Theorie/und oder Datenbanken sind, gibt es einige sehr coole Artikel zu diesem Thema. Dies ist ein toller Artikel für Sie zu beginnen mit: https://www.simple-talk.com/sql/learn-sql-server/sql-and-the-snare-of-three-valued-logic/ –

2

Ich denke, Sie haben einen Fehler in der Dokumentation gefunden, aber es ist nicht auf der Seite, mit der Sie verlinkt haben, sondern auf einer anderen Seite.

den Link in der Frage lautet:

Wenn SET ANSI_NULLSON ist ein Operator, der ein oder zweiNULL Ausdrücke gibt UNKNOWN hat. Wenn SET ANSI_NULLSOFF ist, gelten die gleichen Regeln, außer dass ein Operator gleich (=) TRUE zurückgibt, wenn beide Ausdrücke NULL sind. Zum Beispiel gibt NULL = NULLTRUE zurück, wenn SET ANSI_NULLSOFF ist.

Also, egal, was der Wert, den Sie in SET ANSI_NULLS verwendet wird, wird die Anweisung 1 = null mit einem UNKNOWN Wert führen.

jedoch in der = (Equals) (Transact-SQL) page, die Bemerkungen Abschnitt heißt es:

NULL auf einen Nicht-NULL-Wert Vergleich ergibt immer FALSE.

das ist eindeutig nicht der Fall, da 1 = null nicht FALSE zurückkehrt, kehrt UNKNOWN.

Daher ist meine Schlussfolgerung, dass ein Fehler in der Dokumentation der = Operator-Dokumentation ist.

+0

Ja, wie ich oben schrieb, habe ich den falschen Link gepostet. Ich habe von der anderen Seite zitiert, wie Sie gesagt haben. Ich habe ein Feedback an Microsoft geschrieben, hoffentlich werden sie es korrigieren. Danke fürs Schreiben, ich werde dich aufrüsten, sobald ich das Recht dazu habe (brauche 15 Punkte) – askolotl

+0

Ich denke, die korrekt zitierte Dokumentation ist auch hier falsch. Versuchen Sie die Aussage "SELECT 'es funktioniert!" WHERE 1! = NULL "mit SET ANSI_NULLS ON und OFF und überprüfen, dass mit ANSI_NULL OFF, die WHERE-Klausel als wahr ausgewertet wird (getestet selbst auf Version 12 SP3). Mit ANSI_NULLS ON führt jede WHERE/AND-Klausel mit einem NULL-Vergleich zu UNKNOWN, was dann als false interpretiert wird. NOT UNKNOWN ist immer noch UNBEKANNT und somit immer noch falsch. Verwenden Sie ANSI_NULLS ON und "IS (NOT) NULL" als a_horse_with_no_name, auf das bereits in seinem Kommentar zu der ursprünglichen Frage hingewiesen wurde. –

+0

@HenkKok: Deshalb habe ich Tanner's asnwer aufgewertet. –

2

See: SET ANSI_NULLS (Transact-SQL)

Gibt ISO-konformes Verhalten des Equals (=) und Ungleich (<>) Vergleichsoperator, wenn sie mit Null-Werten in SQL Server 2016.

verwendet werden

In einer zukünftigen Version von SQL Server wird ANSI_NULLS immer aktiviert sein und alle Anwendungen, die explizit die Option auf OFF festlegen, werden einen Fehler generieren. Vermeiden Sie die Verwendung dieser Funktion in neuen Entwicklungsarbeiten, und planen Sie, Anwendungen zu ändern, die diese Funktion derzeit verwenden.

Also, wenn Sie diese verwenden und setzen Sie ihn auf OFF, wird Ihr Code funktioniert wie gewünscht:

SET ANSI_NULLS OFF 

select 'true' where (1 = NULL) ; 

select 'true' where not (1 = NULL) ; 

Aber wie in dem Dokument angegeben ist, wird es Fehler in der Zukunft führen.

1

bessere Art und Weise zu überprüfen oder Vergleichswert mit NULL

select 'true' where 1 IS NULL ; 

select 'true' where 1 IS NOT NULL ; 
+0

Ja , Vielen Dank. Nun, ich hatte einen Ausdruck wie 'WHERE NOT (x.a = y.b)'. Und das hat nicht richtig funktioniert, wenn 'y.b' NULL war, anstatt einen 'regulären' Wert zu haben. – askolotl

+0

Ich schlage vor, Sie sollten wie folgt überprüfen: 'WHERE x.a = y.b UND y.b IST NICHT NULL' –

+0

Aber das ist nicht das Gleiche;) – askolotl

Verwandte Themen