Oracle PL/SQL字符串比较问题

C.c*_*C.c 22 sql oracle plsql oracle10g oracle11g

1).你好,我有以下Oracle PL/SQL代码可能会从你们看来生锈:

 DECLARE
 str1  varchar2(4000);
 str2  varchar2(4000);
 BEGIN
   str1:='';
   str2:='sdd';
   IF(str1<>str2) THEN
    dbms_output.put_line('The two strings is not equal');
   END IF;
 END;
 /
Run Code Online (Sandbox Code Playgroud)

这很明显,两个字符串str1和str2不相等,但为什么'两个字符串不相等'没有打印出来?Oracle有另一种比较两个字符串的常用方法吗?

Wol*_*olf 47

正如Phil所说,空字符串被视为NULL,而NULL不等于或等于任何东西.如果您期望空字符串或NULL,则需要处理以下内容NVL():

 DECLARE
 str1  varchar2(4000);
 str2  varchar2(4000);
 BEGIN
   str1:='';
   str2:='sdd';
-- Provide an alternate null value that does not exist in your data:
   IF(NVL(str1,'X') != NVL(str2,'Y')) THEN
    dbms_output.put_line('The two strings are not equal');
   END IF;
 END;
 /
Run Code Online (Sandbox Code Playgroud)

关于空比较:

按照上NULLS的Oracle 12c的文档,空比较使用IS NULLIS NOT NULL不计算为TRUEFALSE.然而,所有其他比较评估UNKNOWN,而不是 FALSE.文件进一步指出:

计算到UNKNOWN的条件几乎就像FALSE.例如,在WHERE子句中具有计算结果为UNKNOWN的条件的SELECT语句不返回任何行.但是,评估为UNKNOWN的条件与FALSE的不同之处在于UNKNOWN条件评估的进一步操作将评估为UNKNOWN.因此,NOT FALSE计算结果为TRUE,但NOT UNKNOWN计算结果为UNKNOWN.

Oracle提供了一个参考表:

Condition       Value of A    Evaluation
----------------------------------------
a IS NULL       10            FALSE
a IS NOT NULL   10            TRUE        
a IS NULL       NULL          TRUE
a IS NOT NULL   NULL          FALSE
a = NULL        10            UNKNOWN
a != NULL       10            UNKNOWN
a = NULL        NULL          UNKNOWN
a != NULL       NULL          UNKNOWN
a = 10          NULL          UNKNOWN
a != 10         NULL          UNKNOWN
Run Code Online (Sandbox Code Playgroud)

我还了解到我们不应该编写PL/SQL,假设空字符串将始终计算为NULL:

Oracle数据库当前将长度为零的字符值视为null.但是,在将来的版本中,这可能不会继续存在,Oracle建议您不要将空字符串视为与空值相同.

  • 虽然实际上是正确的,但精确的定义是"任何涉及NULL值的比较将始终返回FALSE"(即使与另一个NULL值进行比较).所以:(NULL = NULL)= False AND(NULL <> NULL)= FALSE (7认同)

APC*_*APC 11

让我们通过添加逻辑中的其他分支来填补代码中的空白,看看会发生什么:

SQL> DECLARE
  2   str1  varchar2(4000);
  3   str2  varchar2(4000);
  4  BEGIN
  5     str1:='';
  6     str2:='sdd';
  7     IF(str1<>str2) THEN
  8      dbms_output.put_line('The two strings is not equal');
  9     ELSIF (str1=str2) THEN
 10      dbms_output.put_line('The two strings are the same');
 11     ELSE
 12      dbms_output.put_line('Who knows?');
 13     END IF;
 14   END;
 15  /
Who knows?

PL/SQL procedure successfully completed.

SQL>
Run Code Online (Sandbox Code Playgroud)

所以两个字符串既不相同也不相同?咦?

归结为此.Oracle将空字符串视为NULL.如果我们尝试比较NULL和另一个字符串,结果不是TRUE也不是FALSE,它是NULL.即使另一个字符串也是NULL,情况仍然如此.