嗨,今天我遇到了奇怪的情况。我有一个 where 子句 where was 条件返回字符串,我想检查它是否为空。当它返回空字符串时,Oracle 仍然将其视为不同的字符串。所以我进一步准备了简单的查询:
select 1 from dual where 1 = 1;
returns: 1
select 1 from dual where 'A' = 'A';
returns: 1
Run Code Online (Sandbox Code Playgroud)
现在我无法理解的是:
select 1 from dual where '' = '';
No result.
Run Code Online (Sandbox Code Playgroud)
即使我检查它们是否不同,仍然没有结果。
select 1 from dual where '' != '';
No result.
Run Code Online (Sandbox Code Playgroud)
有人能为我解释一下吗?
原因正如 @Captain Kenpachi 所解释的。如果想要比较两个字符串(或其他相同的类型)并且想要容忍 NULL(或 Oracle 中的空字符串,因为它将其视为相同),那么您需要进行 IS 测试。
您可以尝试使用永远不会使用的流氓值的常见作弊方法,但墨菲定律规定有一天会有人这样做。这种技术也有一个缺点,即流氓值应该与您正在比较的事物的类型相匹配,即比较字符串您需要流氓字符串,而比较日期您需要流氓日期。这也意味着您无法不加思考地随意剪切和粘贴它。例子:
WHERE NVL(col1,'MyRougeValue')=NVL(col2,'MyRougeValue')
标准版本是显式测试 NULL
WHERE (col1=col2 OR (col1 IS NULL AND col2 IS NULL))
相反就变成了WHERE NOT(col1=col2 OR (col1 IS NULL AND col2 IS NULL))
我看过一个冗长的相反版本(如 Toad 的数据比较工具中所示)
WHERE (col1<>col2 OR (col1 IS NULL AND col2 IS NOT NULL) OR (col1 IS NOT NULL AND col2 IS NULL))
Oracle 确实有一个方便的DECODE函数,基本上是 ,IF a IS b THEN c ELSE d所以相等是WHERE DECODE(col1,col2,1,0)=1,相反是WHERE DECODE(col1,col2,1,0)=0。您可能会发现这比显式 IS 测试慢一点。它是 Oracle 专有的,但有助于弥补空字符串问题。