LNNVL Begründung


12

LNNVL ist eine in Oracle integrierte Funktion , die TRUE für Bedingungen zurückgibt, die zu FALSE oder UNKNOWN ausgewertet werden, und FALSE für Bedingungen, die zu TRUE ausgewertet werden. Meine Frage ist, was der Vorteil wäre, das Gegenteil der Wahrheitsbedingung zurückzugeben, anstatt nur mit den NULL-Werten umzugehen.

Angenommen, Sie haben eine Emp-Tabelle mit den Spalten StartCommission und CurrentCommission, die Nullen enthalten können. Folgendes gibt nur Zeilen mit keinem Wert null zurück:

SELECT * FROM Emp WHERE StartCommission = CurrentCommission;

Wenn Sie Zeilen einschließen möchten, in denen eine der beiden Provisionen null ist, können Sie Folgendes tun:

SELECT * FROM Emp WHERE StartCommission = CurrentCommission 
OR StartCommission IS NULL OR CurrentCommission IS NULL;

Es scheint, als ob eine Funktion existieren würde, um diese Syntax zu verkürzen. Wenn Sie jedoch LNNVL verwenden, werden alle ungleichen Datensätze und alle Datensätze mit Nullen zurückgegeben.

SELECT * FROM Emp WHERE LNNVL(StartCommission = CurrentCommission);

Wenn Sie NOT hinzufügen, werden nur Zeilen ohne Nullen zurückgegeben. Es scheint mir, dass die gewünschte Funktionalität für diesen Fall darin besteht, die wahren Bedingungen wahr und die falschen Bedingungen falsch zu halten und unbekannte Bedingungen als wahr zu bewerten. Habe ich hier wirklich einen Low Use Case erstellt? Ist es wirklich wahrscheinlicher, Unbekanntes in Wahres, Wahres in Falsches und Falsches in Wahres verwandeln zu wollen?

create table emp (StartCommission Number(3,2), CurrentCommission Number(3,2));
insert into emp values (null,null);
insert into emp values (null,.1);
insert into emp values (.2,null);
insert into emp values (.3,.4);

Heute habe ich LNNVL getroffen und ich versuche auch diesen Teil herauszufinden oder zu verstehen, "was der Vorteil wäre, das Gegenteil der Wahrheit zurückzugeben". Die Anweisung, die Sie als Beispiel für LNNVL verwenden, sollte jedoch den Operator ungleich verwenden: SELECT * FROM Emp WHERE LNNVL (StartCommission <> CurrentCommission); so dass es dasselbe Ergebnis wie die Anweisung mit ORs zurückgibt. Mit anderen Worten, wenn wir eine Bedingung verwenden und auch Zeilen mit NULL-Wert einschließen möchten, müssen wir das Negat unserer Bedingung an LNNVL übergeben.
Nur Sie

Ein weiteres einfaches Beispiel. Nur Mitarbeiter, die tatsächlich eine Provision von weniger als 20% erhalten: SELECT * FROM Mitarbeiter WHERE commission_pct <.2; Um auch Mitarbeiter einzubeziehen, die überhaupt keine Provision erhalten: SELECT * FROM Mitarbeiter WHERE LNNVL (commission_pct> = .2);
Nur Sie

@OnlyYou - Sie haben Recht, dass die Bedingung <> sein muss, damit LNNVL funktioniert. Ich habe es = more gelassen, da es sinnvoller wäre, wenn die Funktion dieselben Ergebnisse mit dem Zeichen = zurückliefern würde. Im Wesentlichen führt die Funktion zwei Aktionen aus: 1. Null-Inklusion, 2. Boolesches Umschalten. Ersteres macht Sinn, letzteres scheint nur das Gegenteil der gewünschten Bedingung zu verwirren. ie = erfordert <>, <erfordert> =, etc.
Leigh Riffel

Antworten:


6

Es ist eine seltsame Funktion mit einer seltsamen Geschichte - aber dann ist nvl2 seltsam. lnnvlist im Grunde genommen ein is not trueOperator - zweifellos kann er wie ein nvl2Dose verwendet werden. Wenn Sie jedoch jedes Mal eine Funktion nachschlagen müssen, um sich genau daran zu erinnern, was sie tut, müssen Sie sich fragen, ob es am besten ist, sie beizubehalten nvl, coalesce, decodeund nullifzusammen mit caseAusdrücken, die intuitiver sind


Ich finde NVL2 nicht sonderbar, aber dann benutze ich es oft und habe noch nie LNNVL verwendet.
Leigh Riffel

@Leigh - Ich denke, du musst es nur oft genug benutzen, damit es nicht komisch wird :) Ich habe es nie benutzt, nullifbis mir klar wurde, dass es eine große Hilfe sein kann, 'Division durch Null' = Null zu machen. Finden Sie nvl2 (a, c, b) wirklich viel besser als decodieren (a, null, b, c)?
Jack sagt, versuchen Sie topanswers.xyz

4

Um es so auszudrücken: Ich habe LNNVL in meinen mehreren Jahren als DBA- und PL / SQL-Programmierer noch nicht einmal verwendet. Ich habe gelegentlich NVL2 verwendet (und musste immer nachsehen, welche Seite wahr ist und welche nicht). Zu diesem Zeitpunkt erscheint es aus Sicht der Lesbarkeit besser, NVL, DECODE, CASE usw. zu verwenden.

Alternativ funktioniert dies, vorausgesetzt, man hat einen guten Überblick darüber, wie Oracle mit NULL und Arithmetik umgeht. Zu diesem Zeitpunkt kann man jedoch auch Ihre ursprüngliche Abfrage für die Lesbarkeit verwenden (und der Ausführungsplan ist möglicherweise auch schwerer zu treffen):

/* Return all rows where StartCommission is the same
 * as Current Commission, or those rows who have a
 * NULL in either (including both)
 */

SELECT *
  FROM Emp
 WHERE StartCommission = CurrentCommission
    OR StartCommission + CurrentCommission IS NULL

-- NULL + NULL, or NULL + Number is always NULL; hence return either
-- those records that are equal, or have a combined total of NULL
-- (either or both fields will be NULL).

Meinst du StartCommission<>CurrentCommission OR StartCommission + CurrentCommission IS NULL?
Jack sagt, versuchen Sie topanswers.xyz

@ JackPDouglas - Es macht Sinn als =.
Leigh Riffel

Interessante Abwechslung. Ich stimme Ihren Schlussfolgerungen zu.
Leigh Riffel

@Leigh - Ich sehe, eine Alternative zu der gewünschten Funktion, keine Alternative zu lnnvl.
Jack sagt, versuchen Sie topanswers.xyz

@JackPDouglas - Ich verstehe und ich denke, das ist, was Kerri beabsichtigt hat.
Leigh Riffel
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.