Warum behandelt Oracle 9i eine leere Zeichenfolge als NULL?


216

Ich weiß , dass es nicht so betrachten ‚‘ NULL, aber das bedeutet nicht viel , mir zu sagen , warum dies der Fall ist. Nach meinem Verständnis der SQL-Spezifikationen ist '' nicht dasselbe wie NULL- eines ist ein gültiges Datum, und das andere zeigt das Fehlen derselben Informationen an.

Sie können gerne spekulieren, aber bitte geben Sie an, ob dies der Fall ist. Wenn es jemanden von Oracle gibt, der dies kommentieren kann, wäre das fantastisch!


9
Fühlen Sie sich frei zu spekulieren? Irgendwie glaube ich nicht, dass Sie die besten Antworten erhalten.
SCdF

1
Ich nehme nicht an, aber ich war mir nicht sicher, ob es eine Gewissheit zu diesem Thema geben würde, also dachte ich, ich würde die Türen öffnen. Scheint bisher gut geklappt zu haben.
Chris R


Antworten:


216

Ich glaube, die Antwort ist, dass Oracle sehr, sehr alt ist.

In den alten Tagen, bevor es einen SQL-Standard gab, traf Oracle die Entwurfsentscheidung, dass leere Zeichenfolgen in VARCHAR/ VARCHAR2Spalten vorhanden waren NULLund dass es nur einen Sinn für NULL gab (es gibt relationale Theoretiker, die zwischen Daten unterscheiden würden, nach denen nie gefragt wurde). Daten, bei denen die Antwort vorhanden ist, dem Benutzer jedoch nicht bekannt ist, Daten, bei denen keine Antwort vorliegt usw., die alle einen Sinn für NULL) darstellen.

Zu dem Zeitpunkt, als der SQL-Standard eingeführt wurde und zustimmte, dass NULLund die leere Zeichenfolge unterschiedliche Entitäten waren, gab es bereits Oracle-Benutzer, deren Code davon ausging, dass beide gleichwertig waren. Oracle hatte also im Grunde die Möglichkeit, vorhandenen Code zu beschädigen, gegen den SQL-Standard zu verstoßen oder eine Art Initialisierungsparameter einzuführen, der die Funktionalität einer möglicherweise großen Anzahl von Abfragen ändern würde. Die Verletzung des SQL-Standards (IMHO) war die am wenigsten störende dieser drei Optionen.

Oracle hat die Möglichkeit offen gelassen, dass sich der VARCHARDatentyp in einer zukünftigen Version ändert, um dem SQL-Standard zu entsprechen (weshalb jeder VARCHAR2in Oracle verwendet, da das Verhalten dieses Datentyps in Zukunft garantiert gleich bleibt).


60

Tom Kyte VP von Oracle:

Ein Varchar mit der Länge NULL wird als NULL behandelt.

'' wird nicht als NULL behandelt.

'', wenn es einem Zeichen (1) zugewiesen wird, wird '' (Zeichentypen sind leere aufgefüllte Zeichenfolgen).

'', wenn es einem varchar2 (1) zugewiesen wird, wird '', was eine Zeichenfolge mit der Länge Null ist und eine Zeichenfolge mit der Länge Null ist NULL in Oracle (es ist nicht lang '')


17
Wow, Tom ist ziemlich bissig. Angesichts der Tatsache, dass sich die Fragen auf eine ungeheure Abweichung von SQL92 beziehen, würde man meinen, er wäre weniger schlagkräftig ... obwohl er es vielleicht leid sein könnte, darauf zu antworten.
Chris R

8
Das Beste an Tom ist, dass Sie eine klare Antwort erhalten, die genau angibt , was er denkt. Suchen Sie nach einigen Kommentaren, in denen Leute Text verwendet haben, sprechen Sie auf Ask Tom
Chris Gill

9
Es wäre jedoch genauer, wenn die zweite Zeile in ''
Ypercubeᵀᴹ

2
@ypercube Das Zitat wird nicht präziser, wenn das von Tom tatsächlich verwendete Wort geändert wird. Wenn Sie denken, Tom hat es verwirrend formuliert, mmm. Vielleicht. Ich denke, er ist genau richtig . Die verwirrenden Situationen entstehen , wenn ''wird implizit in einen VARCHAR2 umgewandelt, wie cast('' as char(1)) is nulldie ... raschend TRUE
sähe

1
@sehe das verwirrende Bit für mich ist 1 aus Dual auswählen, wobei ('' null ist)
Matt Freake

20

Ich vermute, dass dies viel sinnvoller ist, wenn Sie Oracle so betrachten, wie es frühere Entwickler wahrscheinlich getan haben - als verherrlichtes Backend für ein Dateneingabesystem. Jedes Feld in der Datenbank entsprach einem Feld in einer Form, die ein Dateneingabebetreiber auf seinem Bildschirm sah. Wenn der Bediener nichts in ein Feld eingegeben hat, sei es "Geburtsdatum" oder "Adresse", sind die Daten für dieses Feld "unbekannt". Ein Operator kann nicht angeben, dass die Adresse einer Person wirklich eine leere Zeichenfolge ist, und das macht sowieso nicht viel Sinn.


5
Dies ist nur dann sinnvoll, wenn Sie davon ausgehen, dass jedes Feld in einem Dateneingabesystem obligatorisch ist. Eine Nichtantwort auf ein nicht obligatorisches Feld (z. B. "Name des Hundes") ist gültig, sodass eine leere Zeichenfolge immer noch einen anderen Zweck als NULL hat. Selbst mit dieser Annahme bezweifle ich, dass frühe Entwickler Oracle als "verherrlichtes Backend für ein Dateneingabesystem" angesehen haben, daher bin ich mir nicht sicher, ob diese Antwort überhaupt Sinn macht.
Jared

19

Die Oracle-Dokumentation weist Entwickler auf dieses Problem hin und reicht mindestens bis Version 7 zurück.

Oracle entschied sich dafür, NULLS durch die "Unmögliche Wert" -Technik darzustellen. Beispielsweise wird ein NULL-Wert an einer numerischen Stelle als "minus Null" gespeichert, ein unmöglicher Wert. Alle Minus-Nullen, die sich aus Berechnungen ergeben, werden vor dem Speichern in eine positive Null umgewandelt.

Oracle entschied sich fälschlicherweise auch dafür, die VARCHAR-Zeichenfolge mit der Länge Null (die leere Zeichenfolge) als unmöglichen Wert und als geeignete Wahl für die Darstellung von NULL zu betrachten. Es stellt sich heraus, dass die leere Zeichenfolge weit von einem unmöglichen Wert entfernt ist. Es ist sogar die Identität unter der Operation der String-Verkettung!

Die Oracle-Dokumentation warnt Datenbankdesigner und -entwickler, dass eine zukünftige Version von Oracle diese Zuordnung zwischen der leeren Zeichenfolge und NULL möglicherweise aufheben und jeden Code aufheben kann, der von dieser Zuordnung abhängt.

Es gibt Techniken, um andere NULL-Werte als unmögliche Werte zu kennzeichnen, aber Oracle hat sie nicht verwendet.

(Ich verwende das Wort "Ort" oben, um den Schnittpunkt einer Zeile und einer Spalte zu bezeichnen.)


Die Oracle-Dokumentation warnt Datenbankdesigner und -entwickler, dass eine zukünftige Version von Oracle diese Zuordnung zwischen der leeren Zeichenfolge und NULL möglicherweise aufheben und jeden Code aufheben kann, der von dieser Zuordnung abhängt. Können Sie bitte eine Referenz für diese Anweisung angeben?
Piotr Dobrogost


2

Leere Zeichenfolge ist dasselbe wie NULL, einfach weil es das "geringere Übel" ist, verglichen mit der Situation, in der die beiden (leere Zeichenfolge und Null) nicht gleich sind.

In Sprachen, in denen NULL und leerer String nicht identisch sind, müssen immer beide Bedingungen überprüft werden.


Legen Sie einfach die not nullEinschränkung für Ihre Spalte fest und überprüfen Sie nur die leere Zeichenfolge.
Egor Skriptunoff

6
Das Überprüfen beider Bedingungen ist trivial: WHERE Field <> ''Gibt in Datenbanken mit ANSI-Verhalten für leere Zeichenfolgen nur dann true zurück, wenn das Feld nicht NULL und nicht leer ist.

1

Laut offiziellen 11g-Dokumenten

Oracle Database behandelt derzeit einen Zeichenwert mit einer Länge von Null als Null. Dies gilt jedoch möglicherweise auch in zukünftigen Versionen nicht mehr. Oracle empfiehlt, leere Zeichenfolgen nicht wie Nullen zu behandeln.

Mögliche Gründe

  1. val IS NOT NULL ist besser lesbar als val != ''
  2. Es ist nicht erforderlich, beide Bedingungen zu überprüfen val != '' and val IS NOT NULL

5
In einer vollständig ANSI-kompatiblen Datenbank müssen Sie nicht nach beiden Bedingungen suchen. val <> ''schließt bereits aus NULL. Vielleicht hast du es gemeint val = '' OR val IS NULL. Aber leere Zeichenfolgen, die nicht als NULL verglichen werden, sind nützlich !
ErikE

Ich stimme dem Vergleichsteil zu.
Sortierer

0

Beispiel aus dem Buch

   set serveroutput on;   
    DECLARE
    empty_varchar2 VARCHAR2(10) := '';
    empty_char CHAR(10) := '';
    BEGIN
    IF empty_varchar2 IS NULL THEN
    DBMS_OUTPUT.PUT_LINE('empty_varchar2 is NULL');
    END IF;


    IF '' IS NULL THEN
    DBMS_OUTPUT.PUT_LINE(''''' is NULL');
    END IF;

    IF empty_char IS NULL THEN
    DBMS_OUTPUT.PUT_LINE('empty_char is NULL');
    ELSIF empty_char IS NOT NULL THEN
    DBMS_OUTPUT.PUT_LINE('empty_char is NOT NULL');
    END IF;

    END;

-1

Weil es auch nicht besonders hilfreich ist, es nicht als NULL zu behandeln.

Wenn Sie in diesem Bereich bei Oracle einen Fehler machen, bemerken Sie dies normalerweise sofort. In SQL Server scheint es jedoch zu funktionieren, und das Problem tritt nur auf, wenn jemand eine leere Zeichenfolge anstelle von NULL eingibt (möglicherweise aus einer .net-Clientbibliothek, in der sich null von "" unterscheidet, Sie diese jedoch normalerweise gleich behandeln ).

Ich sage nicht, dass Oracle Recht hat, aber es scheint mir, dass beide Wege ungefähr gleich schlecht sind.


2
Viel, viel einfacher zu debuggen. Wenn Sie eine leere Zelle oder Eingabe auf dem Bildschirm sehen, wissen Sie, dass die Daten in der Datenbank null sind. In anderen DBs, in denen '' <> NULL ist, können Sie nicht "sehen", ob die Daten null oder '' sind. Dies führt zu sehr hinterhältigen Fehlern. '' = null ist die vernünftigste Option, auch wenn sie nicht Standard ist.
Lucio M. Tato

2
"In anderen DBs, in denen '' <> NULL ist, können Sie nicht" sehen ", ob die Daten null sind oder ''" => Normalerweise zeigen DB-Tools NULL-Werte anders an als leere Zeichenfolgen. Tatsächlich zeigt sogar Oracle SQL Developer NULL-Werte als "(null)" an. Ich denke, dies dient dazu, NULL von Leerzeichen zu unterscheiden, aber es hängt nicht mit dem Unterschied zwischen NULL und leeren Zeichenfolgen zusammen.
Didier L

-6

In der Tat hatte ich nur Schwierigkeiten im Umgang mit Oracle, einschließlich ungültiger Datums- / Uhrzeitwerte (kann nicht gedruckt, konvertiert oder irgendetwas, nur mit der DUMP () - Funktion betrachtet werden), die anscheinend durch einen Buggy in die Datenbank eingefügt werden dürfen Version des Clients als Binärspalte! Soviel zum Schutz der Datenbankintegrität!

Oracle-Behandlung von NULL-Links:

http://digitalbush.com/2007/10/27/oracle-9i-null-behavior/

http://jeffkemponoracle.com/2006/02/empty-string-andor-null.html


1
ungültige Datenzeitwerte? Nicht sicher, was das heißt. Haben Sie dies hier als Frage gepostet?

1
Das Problem vor dem Stackoverflow - Ich habe keine nützlichen Informationen aus Oracle-Foren erhalten und eine Problemumgehung erstellt. Ich werde meine Notizen aufspüren und hier veröffentlichen.
Cade Roux

Details als Frage hier gepostet.
Cade Roux

-6

Erstens wurden null und null string von Oracle nicht immer als gleich behandelt. Eine Nullzeichenfolge ist per Definition eine Zeichenfolge, die keine Zeichen enthält. Dies ist überhaupt nicht dasselbe wie eine Null. NULL ist per Definition das Fehlen von Daten.

Vor ungefähr fünf oder sechs Jahren wurde die Nullzeichenfolge von Oracle anders behandelt als die Null. Während, wie null, null string gleich allem war und sich von allem unterschied (was meiner Meinung nach für null in Ordnung ist, aber für null string völlig FALSCH), würde mindestens die Länge (null string) 0 zurückgeben, wie es sollte, da null string ist eine Zeichenfolge mit der Länge Null.

Derzeit gibt in Oracle die Länge (null) null zurück, was meiner Meinung nach in Ordnung ist, aber die Länge (null string) gibt auch null zurück, was völlig FALSCH ist.

Ich verstehe nicht, warum sie beschlossen haben, diese beiden unterschiedlichen "Werte" gleich zu behandeln. Sie bedeuten verschiedene Dinge und der Programmierer sollte die Fähigkeit haben, auf unterschiedliche Weise auf jedes zu reagieren. Die Tatsache, dass sie ihre Methodik geändert haben, zeigt mir, dass sie wirklich keine Ahnung haben, wie diese Werte behandelt werden sollen.


Zitieren erforderlich, um zwischen "Nullzeichenfolge" und NULL-Wert zu unterscheiden. In jeder Datenbank außer Oracle kann ein VARCHARFeld einen Wert (null oder mehr Zeichen) oder keinen Wert (NULL) haben.

"Vor fünf oder sechs Jahren" ab 2011 würde in den Zeitrahmen von 10 g fallen (10.1 veröffentlicht 2003, 10.2 2005). 10g hat absolut keine globalen Änderungen in der Behandlung von Nullen eingeführt, und es gab nie eine Unterscheidung zwischen NULLund einer nullwertigen Zeichenfolge, und eine solche Unterscheidung macht keinen Sinn. Ich fürchte, diese Antwort ist eine völlige Fantasie.
William Robertson
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.