380 Stimmen

Nicht gleich <> != Operator auf NULL

Könnte jemand bitte das folgende Verhalten in SQL erklären?

SELECT * FROM MyTable WHERE MyColumn != NULL (0 Results)
SELECT * FROM MyTable WHERE MyColumn <> NULL (0 Results)
SELECT * FROM MyTable WHERE MyColumn IS NOT NULL (568 Results)

9voto

dkretz Punkte 36862

Der einzige Test für NULL ist IS NULL oder IS NOT NULL. Die Prüfung auf Gleichheit ist unsinnig, weil man per Definition nicht weiß, was der Wert ist.

Hier ist ein Wikipedia-Artikel zu lesen:

https://en.wikipedia.org/wiki/Null_(SQL)

8voto

Manngo Punkte 10358

null steht für keinen Wert oder einen unbekannten Wert. Er gibt nicht an warum gibt es keinen Wert, was zu einer gewissen Unklarheit führen kann.

Angenommen, Sie führen eine Abfrage wie diese aus:

SELECT *
FROM orders
WHERE delivered=ordered;

das heißt, Sie suchen nach Zeilen, in denen die ordered y delivered die Daten sind die gleichen.

Was ist zu erwarten, wenn eine oder beide Spalten Null sind?

Da mindestens eines der Daten unbekannt ist, können Sie nicht davon ausgehen, dass die beiden Daten identisch sind. Dies ist auch der Fall, wenn beide Die Daten sind unbekannt: Wie können sie gleich sein, wenn wir nicht einmal wissen, was sie sind?

Aus diesem Grund ist jeder Ausdruck, der null als Wert muss fehlschlagen. In diesem Fall wird er nicht übereinstimmen. Dies ist auch der Fall, wenn Sie das Folgende versuchen:

SELECT *
FROM orders
WHERE delivered<>ordered;

Noch einmal: Wie können wir sagen, dass zwei Werte no das Gleiche, wenn wir nicht wissen, was sie sind.

SQL hat einen speziellen Test für fehlende Werte:

IS NULL

Insbesondere ist es nicht Vergleichen Werte, sondern sucht vielmehr nach fehlt Werte.

Schließlich, was die != Soweit mir bekannt ist, ist dies in keiner der Normen enthalten, aber es wird sehr breit unterstützt. Er wurde hinzugefügt, damit sich Programmierer aus bestimmten Sprachen besser zurechtfinden. Offen gesagt, wenn ein Programmierer Schwierigkeiten hat, sich zu erinnern, welche Sprache er benutzt, hat er einen schlechten Start.

6voto

Vincent Ramdhanie Punkte 100426

NULL Kann mit Hilfe der Vergleichsoperatoren nicht mit einem Wert verglichen werden. NULL = NULL ist falsch. Null ist kein Wert. Der IS-Operator ist speziell für NULL-Vergleiche ausgelegt.

2voto

Yariv de Botton Punkte 39

Ich möchte diesen Code vorschlagen, den ich erstellt habe, um festzustellen, ob sich ein Wert geändert hat, i ist der neue Wert und d das alte (wobei die Reihenfolge keine Rolle spielt). Im Übrigen ist eine Änderung von Wert zu Null oder umgekehrt eine Änderung, aber von Null zu Null nicht (natürlich ist eine Änderung von Wert zu einem anderen Wert eine Änderung, aber von Wert zu demselben Wert nicht).

CREATE FUNCTION [dbo].[ufn_equal_with_nulls]
(
    @i sql_variant,
    @d sql_variant
)
RETURNS bit
AS
BEGIN
    DECLARE @in bit = 0, @dn bit = 0
    if @i is null set @in = 1
    if @d is null set @dn = 1

    if @in <> @dn
        return 0

    if @in = 1 and @dn = 1
        return 1

    if @in = 0 and @dn = 0 and @i = @d
        return 1

    return 0

END

Um diese Funktion zu nutzen, können Sie

declare @tmp table (a int, b int)
insert into @tmp values
(1,1),
(1,2),
(1,null),
(null,1),
(null,null)

---- in select ----
select *, [dbo].[ufn_equal_with_nulls](a,b) as [=] from @tmp

---- where equal ----
select *,'equal' as [Predicate] from @tmp where  [dbo].[ufn_equal_with_nulls](a,b) = 1

---- where not equal ----
select *,'not equal' as [Predicate] from @tmp where  [dbo].[ufn_equal_with_nulls](a,b) = 0

Die Ergebnisse sind:

---- in select ----
a   b   =
1   1   1
1   2   0
1   NULL    0
NULL    1   0
NULL    NULL    1

---- where equal ----
1   1   equal
NULL    NULL    equal

---- where not equal ----
1   2   not equal
1   NULL    not equal
NULL    1   not equal

Die Verwendung von sql_variant macht es kompatibel für eine Vielzahl von Typen

0voto

Shadow Punkte 13

NULL ist nichts...es ist unbekannt. NULL ist nicht gleich irgendetwas. Deshalb müssen Sie die magische Phrase IS NULL anstelle von = NULL in Ihren SQL-Abfragen verwenden

Sie können dies nachlesen: http://weblogs.sqlteam.com/markc/archive/2009/06/08/60929.aspx

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X