Justificación LNNVL

12

LNNVL es una función integrada de oráculo que devuelve VERDADERO para las condiciones que evalúan como FALSO o DESCONOCIDO, y devuelve FALSO para las condiciones que evalúan como VERDADERO. Mi pregunta es ¿cuál sería el beneficio de devolver lo contrario de la condición de verdad en lugar de solo manejar los valores NULL?

Por ejemplo, suponga que tiene una tabla Emp con columnas StartCommission y CurrentCommission que pueden contener valores nulos. Lo siguiente devuelve solo filas sin valor nulo:

SELECT * FROM Emp WHERE StartCommission = CurrentCommission;

Si desea incluir filas donde cualquiera de las comisiones es nula, puede hacer algo como esto:

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

Parecería que existiría una función para acortar esta sintaxis, pero el uso de LNNVL devuelve todos los registros no iguales y todos los registros con valores nulos.

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

Agregar NOT a esto solo devuelve filas sin nulos. Me parece que la funcionalidad deseada para este caso sería mantener las condiciones verdaderas verdaderas, las condiciones falsas falsas y que las condiciones desconocidas se evalúen como verdaderas. ¿Realmente he creado un caso de bajo uso aquí? ¿Es realmente más probable que desee convertir lo desconocido en verdadero, verdadero en falso y falso en verdadero?

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);
Leigh Riffel
fuente
Hoy conocí a LNNVL y estoy tratando de descubrir o comprender también esta parte "cuál sería el beneficio de devolver lo contrario de la verdad". Sin embargo, la declaración que use para ejemplificar LNNVL debe usar el operador no igual: SELECT * FROM Emp WHERE LNNVL (StartCommission <> CurrentCommission); para que devuelva el mismo resultado que la instrucción que usa OR. En otras palabras, si estamos usando una condición y también queremos incluir filas que tengan un valor NULL, debemos pasar la negación de nuestra condición a LNNVL.
Solo tú el
Otro ejemplo simple. Solo empleados que realmente reciben una comisión de menos del 20%: SELECCIONE * DE los empleados DONDE comisión_pct <.2; Para incluir también a los empleados que no reciben ninguna comisión: SELECCIONE * DE los empleados DONDE LNNVL (comisión_pct> = .2);
Solo tú el
@OnlyYou: tiene razón, que para que LNNVL funcione igual, la condición debería ser <>. Lo dejé = más porque si la función devolviera los mismos resultados con el signo = tendría más sentido. Esencialmente, la función está realizando dos acciones 1. Inclusión nula, 2. Alternar booleano. Lo primero tiene sentido, lo último parece confundir cosas que requieren lo contrario de la condición deseada. es decir, requiere <>, <requiere> =, etc.
Leigh Riffel

Respuestas:

6

Es una función extraña con un historial extraño , pero también lo es nvl2 raro. lnnvles básicamente un is not trueoperador; sin duda, se puede usar como nvl2puede, pero cuando tienes que buscar una función cada vez que la usas para recordarte exactamente lo que hace, te preguntas si es mejor seguirla. nvl, coalesce, decodey nullifjunto con caselas expresiones, que son más intuitivo

Jack dice que intente topanswers.xyz
fuente
No me parece extraño NVL2, pero luego lo uso mucho y nunca he usado LNNVL.
Leigh Riffel
@Leigh: supongo que debes usarlo con la frecuencia suficiente para que no se vuelva raro :) Nunca lo usé nullifhasta que me di cuenta de que puede ser de gran ayuda para hacer 'división por cero' = nulo. ¿Realmente encuentras nvl2 (a, c, b) mucho mejor que decodificar (a, null, b, c)?
Jack dice que intente topanswers.xyz
4

Dicho de esta manera, todavía no he usado LNNVL una vez en mis varios años de ser un programador DBA y PL / SQL. He usado NVL2 en ocasiones (y siempre tuve que buscar qué lado era cierto y qué lado no). En ese punto, parece mejor desde una perspectiva de legibilidad terminar usando NVL, DECODE, CASE, etc.

Alternativamente, esto funciona, suponiendo que uno tenga un buen manejo de cómo Oracle maneja los valores NULL y aritméticos, pero en este punto, uno puede usar su consulta original para facilitar la lectura (y el plan de ejecución también puede ser más difícil):

/* 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).
Kerri Shotts
fuente
Qué quiere decir StartCommission<>CurrentCommission OR StartCommission + CurrentCommission IS NULL?
Jack dice que intente topanswers.xyz
@JackPDouglas: tiene sentido como =.
Leigh Riffel
Variación interesante Estoy de acuerdo con tus conclusiones.
Leigh Riffel
@Leigh: ya veo, una alternativa a la función que desea, no una alternativa lnnvl.
Jack dice que intente topanswers.xyz
@JackPDouglas: entiendo y creo que eso es lo que Kerri pretendía.
Leigh Riffel