LNNVL Motivazione


12

LNNVL è una funzione integrata dell'oracolo che restituisce VERO per le condizioni che valutano FALSO o SCONOSCIUTO e restituisce FALSO per le condizioni che valutano VERO. La mia domanda è quale sarebbe il vantaggio di restituire l'opposto della condizione di verità piuttosto che gestire i valori NULL?

Ad esempio, supponiamo di avere una tabella Emp con le colonne StartCommission e CurrentCommission che possono contenere valori null. Quanto segue restituisce solo le righe senza valore nullo:

SELECT * FROM Emp WHERE StartCommission = CurrentCommission;

Se desideri includere righe in cui una delle commissioni è nulla, puoi fare qualcosa del genere:

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

Sembrerebbe che esistesse una funzione per abbreviare questa sintassi, ma l'uso di LNNVL restituisce tutti i record non uguali e tutti i record con valori nulli.

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

L'aggiunta di NOT a questo restituisce solo righe senza valori null. Mi sembra che la funzionalità desiderata per questo caso sarebbe quella di mantenere vere le condizioni vere, false le condizioni e fare in modo che le condizioni sconosciute vengano valutate come vere. Ho davvero creato un caso di scarso utilizzo qui? È davvero più probabile voler trasformare l'ignoto in vero, vero in falso e falso in vero?

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);

Oggi ho incontrato LNNVL e sto cercando di scoprire o comprendere anche questa parte "quale sarebbe il vantaggio di restituire il contrario della verità". Tuttavia, l'istruzione utilizzata per esemplificare LNNVL deve utilizzare l'operatore non uguale: SELEZIONA * DA Emp DOVE LNNVL (StartCommission <> CurrentCommission); in modo che restituisca lo stesso risultato dell'istruzione utilizzando gli OR. In altre parole, se stiamo usando una condizione e vogliamo anche includere righe con valore NULL, dobbiamo passare il negato della nostra condizione a LNNVL.
Solo tu

Un altro semplice esempio. Solo dipendenti che ricevono effettivamente una commissione inferiore al 20%: SELEZIONA * DA dipendenti DOVE commission_pct <.2; Per includere anche i dipendenti che non ricevono alcuna commissione: SELEZIONA * DA dipendenti DOVE LNNVL (commission_pct> = .2);
Solo tu

@OnlyYou - Hai ragione, che per far funzionare LNNVL allo stesso modo la condizione dovrebbe essere <>. L'ho lasciato = più perché se la funzione restituisse gli stessi risultati con il segno = avrebbe più senso. Essenzialmente la funzione sta eseguendo due azioni 1. Inclusione nulla, 2. Attivazione / disattivazione booleana. Il primo ha senso, il secondo sembra solo confondere le cose che richiedono l'opposto della condizione desiderata. ie = richiede <>, <richiede> =, ecc.
Leigh Riffel

Risposte:


6

È una strana funzione con una strana storia - ma anche lo è nvl2 strano. lnnvlè fondamentalmente un is not trueoperatore - senza dubbio può essere messo a frutto come nvl2può, ma quando devi cercare una funzione ogni volta che la usi per ricordarti esattamente cosa fa, ti viene da chiederti se è meglio attenersi nvl, coalesce, decodee nullifinsieme con caseespressioni, che sono più intuitiva


Non trovo strano NVL2, ma poi lo uso molto e non ho mai usato LNNVL.
Leigh Riffel,

@Leigh - Immagino che tu debba usarlo abbastanza spesso perché non diventi strano :) Non l'ho mai usato nulliffino a quando non mi sono reso conto che può essere di grande aiuto rendere 'divisione per zero' = null. Trovi nvl2 (a, c, b) molto meglio della decodifica (a, null, b, c)?
Jack dice di provare topanswers.xyz

4

Detto in questo modo, non ho ancora usato LNNVL da diversi anni come programmatore DBA e PL / SQL. Ho usato NVL2 in alcune occasioni (e ho sempre dovuto cercare da che parte era vera, e da quale parte no). A quel punto, sembra meglio dal punto di vista della leggibilità finire per usare NVL, DECODE, CASE, ecc.,

In alternativa, questo funziona, supponendo che uno abbia una buona padronanza di come Oracle gestisce NULL e l'aritmetica, ma a questo punto, è possibile utilizzare la query originale per leggibilità (e anche il piano di esecuzione potrebbe subire un colpo più duro):

/* 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).

Intendi StartCommission<>CurrentCommission OR StartCommission + CurrentCommission IS NULL?
Jack dice di provare topanswers.xyz

@JackPDouglas - Ha senso come =.
Leigh Riffel,

Variazione interessante Sono d'accordo con le tue conclusioni.
Leigh Riffel,

@Leigh - Vedo, un'alternativa alla funzione che desideri, non un'alternativa a lnnvl.
Jack dice di provare topanswers.xyz

@JackPDouglas - Capisco e penso che sia quello che Kerri intendeva.
Leigh Riffel,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.