Nur eine Frage zum Umgang mit Werten führt zu Nullwerten in einer Abfrage.
Zum Beispiel habe ich die folgende Tabelle mit den folgenden Feldern und Werten
TABLEX
Column1
1
2
3
4
5
---------
Column2
null
A
B
C
null
Ich übergebe eine VariableY für eine bestimmte Prozedur. Innerhalb der Prozedur befindet sich ein solcher Cursor
CURSOR c_results IS
SELECT * FROM TABLEX where column2 = variableY
jetzt ist das Problem variabelY kann entweder Null, A, B oder C sein. Wenn die VariableY Null ist, möchte ich alle Datensätze auswählen, bei denen Spalte2 Null ist, andernfalls ist Spalte2 entweder A, B oder C.
Ich kann den obigen Cursor/die Abfrage nicht ausführen, da VariableY nicht gleich Null ist, weil der Vergleich durchgeführt werden sollte
CURSOR c_results IS
SELECT * FROM TABLEX where column2 IS NULL
Welchen Cursor/welche Abfrage sollte ich verwenden, der entweder eine Null- oder eine String-Variable enthält?.
Sorry, wenn meine Frage etwas verwirrend ist. Ich kann Dinge nicht so gut erklären. Danke im Voraus.
Erzeugen Sie je nach Inhalt dieses Parameters unterschiedliche SQL-Werte oder ändern Sie Ihre SQL-Einstellungen folgendermaßen:
WHERE (column2 = variableY) OR (variableY IS NULL AND column2 IS NULL)
Ask Tom von Oracle sagt:
where decode( col1, col2, 1, 0 ) = 0 -- finds differences
oder
where decode( col1, col2, 1, 0 ) = 1 -- finds sameness - even if both NULL
Die folgende Antwort ähnelt der Antwort "oben", ist jedoch präziser:
WHERE ((column2 = variableY ) or COALESCE( column2, variableY) IS NULL)
Sie könnten so etwas verwenden:
SELECT * FROM TABLEX WHERE COALESCE(column2, '') = COALESCE(variableY, '')
(COALESCE nimmt den ersten Nicht-NULL-Wert an)
Beachten Sie, dass dies nur funktioniert, wenn der Spalteninhalt nicht '' (leere Zeichenfolge) ist. Andernfalls schlägt diese Anweisung fehl, da NULL mit '' (leerer String) übereinstimmt.
(edit) Sie könnten auch Folgendes in Betracht ziehen:
SELECT * FROM TABLEX WHERE COALESCE(column2, 'a string that never occurs') = COALESCE(variableY, 'a string that never occurs')
Damit wird die Fail-Hypothese behoben.
Abhängig von den Daten, die Sie betrachten, ist dies möglicherweise nicht angemessen, aber ein Trick, den ich gesehen (und verwendet) habe, ist der Vergleich von NVL (Feldname, Somenonexistentvalue).
Wenn AGE beispielsweise eine optionale Spalte ist, können Sie Folgendes verwenden:
if nvl(table1.AGE,-1) = nvl(table2.AGE,-1)
Dies setzt voraus, dass es einen Wert gibt, den Sie know niemals zulassen werden. Das Alter ist ein gutes Beispiel, Gehalt, Sequenznummern und andere Zahlen, die nicht negativ sein können. Strings können natürlich komplizierter sein - Sie können sagen, dass Sie niemals jemanden namens "xyzzymaryhadalittlelamb" oder ähnliches haben werden, aber an dem Tag, an dem Sie mit dieser Annahme laufen, wissen Sie, dass sie jemanden mit diesem Namen einstellen !!
Alles, was gesagt wurde: "wo a = b oder (a ist null und b ist null)" ist der traditionelle Weg, es zu lösen. Das ist bedauerlich, da selbst erfahrene Programmierer diesen Teil manchmal vergessen.
Sie könnten DUMP
verwenden:
SELECT *
FROM TABLEX
WHERE DUMP(column2) = DUMP(variableY);
Warnung: Dies ist kein SARG-fähiger Ausdruck, daher gibt es keine Indexverwendung.
Bei diesem Ansatz müssen Sie nicht nach Werten suchen, die in Ihren Daten nicht vorhanden sind (wie NVL/COALESCE
).
Versuchen Sie es mit der Funktion ISNULL()
. Sie können überprüfen, ob die Variable NULL ist. Wenn ja, legen Sie einen Standardrückgabewert fest. Campern von Null auf Null ist nicht wirklich möglich. Denken Sie daran: null <> null
WHERE variableY is null or column2 = variableY
for example:
create table t_abc (
id number(19) not null,
name varchar(20)
);
insert into t_abc(id, name) values (1, 'name');
insert into t_abc(id, name) values (2, null);
commit;
select * from t_abc where null is null or name = null;
--get all records
select * from t_abc where 'name' is null or name = 'name';
--get one record with name = 'name'