在 Oracle SQL 中比较两个空字符串

Raf*_*ski 4 sql oracle

嗨,今天我遇到了奇怪的情况。我有一个 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)

有人能为我解释一下吗?

Cap*_*chi 6

Oracle 将空字符串视为 NULL。这是一个陷阱。记下它并希望它不会在生产中给你带来麻烦。


Uno*_*bre 5

原因正如 @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 专有的,但有助于弥补空字符串问题。