Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle PLSQL-查找两个值在为NULL时相等_Oracle_Plsql_Null - Fatal编程技术网

Oracle PLSQL-查找两个值在为NULL时相等

Oracle PLSQL-查找两个值在为NULL时相等,oracle,plsql,null,Oracle,Plsql,Null,我使用IF条件来检查两个值是否相等。在一个场景中,我使用的所有值都是NULL,但它无法识别它们是否相等 IF training_event_rec_.training_fee = course_rec_.course_fee AND training_event_rec_.training_fee_unit = course_rec_.course_fee_unit AND training_event_rec_.currency = course_rec_.currency AND train

我使用IF条件来检查两个值是否相等。在一个场景中,我使用的所有值都是NULL,但它无法识别它们是否相等

IF training_event_rec_.training_fee = course_rec_.course_fee AND training_event_rec_.training_fee_unit = course_rec_.course_fee_unit AND training_event_rec_.currency = course_rec_.currency AND training_evaluation_temp_ = course_evaluation_temp_ THEN
    RETURN FALSE;
ELSE
     RETURN TRUE;
END IF;
在这里,所有被比较的变量都是空的,但它总是命中ELSE部分。 在这种情况下,如何比较值。

使用为空:

IF     (training_event_rec_.training_fee = course_rec_.course_fee OR
       (training_event_rec_.training_fee IS NULL AND course_rec_.course_fee IS NULL))
   AND (training_event_rec_.training_fee_unit = course_rec_.course_fee_unit OR
        (training_event_rec_.training_fee_unit IS NULL AND course_rec_.course_fee_unit IS NULL))
   AND (training_event_rec_.currency = course_rec_.currency OR
        (training_event_rec_.currency IS NULL AND course_rec_.currency IS NULL))
   AND (training_evaluation_temp_ = course_evaluation_temp_ OR
        (training_evaluation_temp_ IS NULL AND course_evaluation_temp_ IS NULL))
THEN
    RETURN FALSE;
ELSE
     RETURN TRUE;
END IF;
注:

  • 您还可以比较空值,如NVL(列A,'X')=NVL(列B,'X'),前提是您确定列A和列B不包含值“X”。所以这不是推荐的方法

我认为可能存在非空值和空值的不同组合。一个选项是全部选中,或者(可能更简单)使用
NVL
,例如:

IF     nvl(training_event_rec_.training_fee, 0)      = nvl(course_rec_.course_fee, 0)
   AND nvl(training_event_rec_.training_fee_unit, 0) = nvl(course_rec_.course_fee_unit, 0)
   AND nvl(training_event_rec_.currency, 0)          = nvl(course_rec_.currency, 0)
   AND nvl(training_evaluation_temp_, 0)             = nvl(course_evaluation_temp_, 0)
THEN
   RETURN FALSE;
ELSE
   RETURN TRUE;
END IF;
根据数据类型,您可能需要使用其他数据类型,而不是
0
。例如,货币可能是美元或欧元或类似的东西,所以您可以使用

nvl(training_event_rec_.currency, 'x')

使用NVL()的危险在于可能会生成错误匹配。如果
course\u rec.course\u fee
=0且
training\u event\u rec.training\u fee
为空,则它们不相同。也许业务规则说我们可以将它们视为相同的,但没有说明。因此,我认为显式测试为NULL是更安全的解决方案。显式测试为NULL是更安全的选择,除非业务规则给我们一个默认值,我们可以替换为NULL。感谢您提供的信息。起初,我认为再次检查null可能没有效率,正如您提到的,使用NVL对我的业务逻辑来说是不安全的。在某些情况下,您可以指定一个无法与现有值匹配的默认值,尽管正如APC所说,这将取决于您的业务规则和数据模型。例如,如果
课程费
数字(6,2)
,那么它永远不会匹配
0.001
1e9
二进制
,如果
货币
varchar2(3)
,那么它永远不会匹配
“#。(我很想使用
chr(0)
,但我认为这是一种黑客行为。)
null!=空
。这就是为什么测试总是使用ELSE分支。