Grundsätzlich bedeutet ein NULL in SQL Server, dass es keinen Wert gibt und daher nicht verglichen werden kann, was zu unerwarteten Ergebnissen führt.
Beispielsweise gibt die folgende Abfrage keine Zeilen zurück, in denen der Wert NULL ist, aber ich möchte, dass dies der Fall ist:
SELECT *
FROM table
WHERE
(value != 26)
AND date IS NULL
AND last_modified >= '5/21/2014'
Ich verstehe, dass ich Folgendes als Problemumgehung tun kann, aber im Ernst? Müssen Sie jedes Mal, wenn ich es einfügen möchte, Klammern hinzufügen und prüfen, ob für jedes einzelne Feld null ist? Scheint hässlich, nicht intuitiv und verrückt.
SELECT *
FROM table
WHERE
(value != 26 OR value is null)
AND date IS NULL
AND last_modified >= '5/21/2014'
Ich meine, ich weiß, dass NULL kein Wert ist und daher nicht verglichen werden kann, aber können Sie nicht daraus schließen, dass es tatsächlich definitiv nicht 26 ist? Wenn 26 etwas ist und NULL nichts ist und nichts nichts ist, dann ist NULL nicht 26. Scheint mir logisch.
Weiß jemand, wie ich bei der Verwendung von Vergleichen auf sauberere Weise Nullen in meine Ergebnisse aufnehmen kann, ohne jedes Mal eine explizite Prüfung durchführen zu müssen? Auch das Deaktivieren von Nullen auf meinen Tabellen ist definitiv keine Option.
Bearbeiten:
Mein eigentliches Problem, warum ich es nicht so machen will, wie ich es gezeigt habe, wurde nicht aufgedeckt. Also los geht's. Ich schreibe ein Programm, mit dem Sie Abfragen für Datenbanktabellen erstellen und den Benutzer dynamisch Filter erstellen lassen können, die im Wesentlichen am Ende des Tages eine SQL-Anweisung erstellen und die Ergebnisse für den Benutzer anzeigen. Die vom Benutzer ausgewählten Felder können beliebige und / oder alle Felder in einer bestimmten Datenbank sein. Wenn ich diese ISNULL-Prüfung buchstäblich auf jedes einzelne Feld setzen muss, wäre dies wirklich ineffizient und würde das Betrachten von SQL sehr hässlich machen. Mein Programm ist tabellendefinitionsunabhängig, was bedeutet, dass es mir egal ist, was in Ihrer Tabelle enthalten ist, und ich möchte nicht wissen, wie Ihre Tabelle definiert ist. Ich möchte nur, dass Sie eine Tabelle auswählen, einige Felder auswählen, nach denen mit gleich, nicht gleich, in, nicht in usw. gefiltert werden soll.
quelle
Antworten:
Zu Beginn bedeutet NULL nicht "kein Wert", sondern "Unbekannter Wert" in SQL Server. Es gibt eine Sitzungseinstellung mit dem Namen ANSI_NULLS, die dazu führen kann, dass sich Ihre Abfragen so verhalten, wie Sie es möchten. Sie ist jedoch veraltet und wird in einer zukünftigen Version auf ON gesetzt (was Ihnen anscheinend nicht gefällt): http: // msdn .microsoft.com / de-de / library / ms188048.aspx
Ich verstehe, was Sie tun möchten, und um einen Gegenpunkt zu machen, würde ich fragen, ob Sie Fragen gesehen haben, die von Berichtsdiensten oder so etwas wie Cognos generiert wurden. Wenn ja, sehen Sie genau, was Sie beschreiben, was Sie nicht tun möchten. Warum? Nun, mit einem Schema, das Nullen zulässt, ist dies der richtige Weg. Ich sage nicht, dass es eine super tolle und großartige Idee ist, aber sie funktioniert die ganze Zeit.
Was Ihr Designer tun könnte, ist zu überprüfen, ob diese Spalte überhaupt null sein könnte, und wenn ja, könnte die entsprechende Logik sie schrittweise ausführen und die richtige Abfrage erstellen. Sie könnten auch Optionen wie "Diese Spalte ist möglicherweise null, möchten Sie diese Werte?" Haben. Ich kenne das Endspiel per se nicht und das Schreiben eines eigenen dynamischen Abfragetools ist ziemlich schwierig, wenn alle logischen Konsistenzen berücksichtigt werden (wie dieses).
Ich würde weiterhin explizite Nullprüfungen für Spalten durchführen, die möglicherweise null sein könnten. Sicher sieht es nicht gut aus, aber es funktioniert die ganze Zeit.
Die ANSI_NULL-Set-Option funktioniert vorerst, ist jedoch keine gute Idee, insbesondere wenn Sie die Umgebung nicht steuern. Außerdem wird sie später auf ON gesetzt und verursacht Fehler, bei denen Sie Ihre Anwendungslogik ohnehin neu schreiben müssen. Auf diese Weise arbeitet SQL Server mit NULL-Werten.
quelle
Das
NULL
Problem ist ein heikles Problem mit SQL. Es ist im Grunde ein Fehler, der jetzt in alle SQL-Software auf dem Planeten eingebrannt ist. Wir müssen uns darum kümmern.value <> 26 or value is null
ist ein guter Weg, um diese Logik zu implementieren. Es gibt andere Formulierungen derselben Semantik.Wenn Sie wissen, dass dieser Wert niemals
-1
(zum Beispiel) ist, können Sie sagenISNULL(value, -1) <> 26
. Ich denke nicht, dass dies vom Standpunkt der Lesbarkeit aus besser ist. Dies kann auch zu Optimierungsproblemen führen, da dieses Prädikat möglicherweise nicht SARG-fähig ist.value is null
ist ein SARGable und indexable Prädikat, das der landläufigen Meinung widerspricht.SQL hat den
IS DINSTINCT FROM
Operator, T-SQL unterstützt ihn jedoch nicht. Bitte nehmen Sie sich eine Sekunde Zeit, um für den Antrag auf Umsetzung zu stimmen! Es ist ein rein syntaktisches Problem. Der Optimierer muss sich überhaupt nicht ändern. Dieser Operator wird bereits intern unterstützt.TL; DR: Die Art und Weise, wie Sie es gerade tun, ist die richtige. Lebe damit.
quelle