LNNVL证明


12

LNNVL是一个Oracle内置函数,对于评估为FALSE或UNKNOWN的条件返回TRUE,对于评估为TRUE的条件返回FALSE。我的问题是,返回真值条件的对立而不只是处理NULL值有什么好处?

例如,假设您有一个包含StartCommission和CurrentCommission列的Emp表,其中的列可能包含空值。以下仅返回两个都不为null的行:

SELECT * FROM Emp WHERE StartCommission = CurrentCommission;

如果要包括其中任一佣金为null的行,则可以执行以下操作:

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

似乎存在一个可以缩短此语法的函数,但是使用LNNVL会返回所有非相等记录以及所有具有空值的记录。

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

向其添加NOT只会返回不包含null的行。在我看来,这种情况下所需的功能是保持真实条件为真,错误条件为假以及未知条件为真。我真的在这里创建了一个低用例吗?是否真的更有可能想要将未知变成真实,将真实变成虚假,以及将虚假变成真实?

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

今天,我遇到了LNNVL,我也试图找出或理解这一部分“返回真相的反面会有什么好处”。但是,用于示例LNNVL的语句应使用不相等的运算符:SELECT * FROM Emp WHERE LNNVL(StartCommission <> CurrentCommission); 因此它返回的结果与使用OR的语句相同。换句话说,如果使用条件,并且还希望包含具有NULL值的行,则需要将条件的否定值传递给LNNVL。
只有您

另一个简单的例子。仅实际收到低于20%佣金的雇员:SELECT * FROM雇员WHERE_pct <.2; 还包括完全不收取任何佣金的员工:SELECT * FROM WHERE LNNVL(commission_pct> = .2)的员工;
只有您,

@OnlyYou-您是正确的,要使LNNVL相同,条件必须为<>。我将其保留为=更多,因为如果函数确实使用=符号返回相同的结果,则将更有意义。本质上,该函数执行两个操作:1.空包含; 2.布尔切换。前者是有道理的,后者似乎只是混淆了需要与期望条件相反的事物。即=需要<>,<需要> =,等
利Riffel

Answers:


6

这是一个具有怪异历史的怪异函数-但是nvl2也很怪异。lnnvl基本上是一个is not true运算符-毫无疑问,它可以像罐子一样被很好地利用nvl2,但是当您每次使用它时都必须查找一个函数以提醒您确切的功能时,您会怀疑是否最好坚持使用nvlcoalescedecodenullif连同case表情,这是更直观


我没有发现NVL2很奇怪,但是后来我经常使用它,而且我从未使用过LNNVL。
雷·里菲尔

@Leigh-我想您必须经常使用它,以使其变得不奇怪:)我从未使用过,nullif直到我意识到将'零除'= null可以为您提供很大的帮助。您真的发现nvl2(a,c,b)比解码(a,null,b,c)好吗?
杰克说尝试topanswers.xyz 2011年

4

这样说,我在成为DBA和PL / SQL程序员的几年中还没有使用过LNNVL。我偶尔使用过NVL2(并且总是不得不查看哪一侧是正确的,哪一侧不是。)到那时,从可读性的角度来看,最好使用NVL,DECODE,CASE等,

另一种方法是,假设有人对Oracle如何处理NULL和算术有一个很好的了解,这种方法行得通,但是,到那时,您最好还是使用原始查询来提高可读性(执行计划也可能会受到更大的打击):

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

你是说StartCommission<>CurrentCommission OR StartCommission + CurrentCommission IS NULL
杰克说,请尝试topanswers.xyz 2011年

@JackPDouglas-有意义=。
雷·里菲尔

有趣的变化。我同意你的结论。
雷·里菲尔

@Leigh-我看到了,它是您想要的功能的替代品,而不是的替代品lnnvl
杰克说尝试topanswers.xyz 2011年

@JackPDouglas-我了解,我认为那是Kerri的意图。
雷·里菲尔
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.