【问题标题】:Oracle PL/SQL string comparison on string literals: unexpected result字符串文字上的 Oracle PL/SQL 字符串比较:意外结果
【发布时间】:2015-12-14 00:12:03
【问题描述】:

这是一个关于 Oracle PL/SQL 中字符串比较的问题。我正在测试一些涉及空白填充和非空白填充比较的简单 sn-ps,我遇到了一个特定情况,我无法了解 PL/SQL 引擎在做什么。

这是我的代码(我在 Oracle 12c 上运行此脚本)

set serveroutput on;
declare
   l_char1      char(35)     := 'Hello';
   l_char2      char(30)     := 'Hello  ';
   l_varchar21  varchar2(35) := 'Hello';
   l_varchar22  varchar2(35) := 'Hello  ';
begin
   /* When a comparison is made between variables of type CHAR, 
   a blank-padding comparison takes place. */
   if ( l_char1 = l_char2) then
      dbms_output.put_line('First comparison is TRUE');
   else
      dbms_output.put_line('First comparison is FALSE');
   end if;

   /* When at least one of the involved variables is a VARCHAR2, 
   then a non-blank-padding comparison takes place. None of the     
   variables involved in the comparison is then modified. */
   if ( l_char1 = l_varchar21) then
      dbms_output.put_line('Second comparison is TRUE');
   else
      dbms_output.put_line('Second comparison is FALSE');
   end if;

   /* yet another non-blank-padding comparison */
   if ( l_varchar21 = l_varchar22) then
      dbms_output.put_line('Third comparison is TRUE');
   else
      dbms_output.put_line('Third comparison is FALSE');
   end if;

   /* Strange behaviour: I supposed both string literals to be
   treated as VARCHAR2, so I expected to get FALSE. */
   if ( 'MP' = 'MP ') then
      dbms_output.put_line('Fourth comparison is TRUE');
   else
      dbms_output.put_line('Fourth comparison is FALSE');
   end if;
end;

这是输出

Procedura PL/SQL completata correttamente.
First comparison is TRUE
Second comparison is FALSE
Third comparison is FALSE
Fourth comparison is TRUE    ** I expected FALSE **

关于字符串文字比较,我希望得到Oracle documentation 上报告的内容;我引用关键句:

尾随空格在字符串文字中很重要,因此 'abc' 和 'abc ' 是不同的。在 PL/SQL 处理过程中,字符串文字中的尾随空格不会被修剪,但如果将该值插入到 CHAR 类型的表列中,它们会被修剪。有关其他信息,包括 NCHAR 字符串文字,请参阅“字符串文字”。

有什么想法可以解释我的发现吗?这是否取决于我的 Oracle 环境/会话中的特定设置?

【问题讨论】:

    标签: oracle plsql string-comparison


    【解决方案1】:

    这是因为 'MP' 和 'MP' 是 CHAR 值,并且 oracle 会自动将您分配给该变量的任何值填充为指定的最大长度的空格

    如果声明长度大于 1 的 CHAR 变量,Oracle 数据库自动填充您分配给该变量的任何值 空格到最大长度

    请参阅与您的示例类似的 OraMag 文章 http://www.oracle.com/technetwork/issue-archive/2011/11-sep/o51plsql-453456.html

    BEGIN
      IF 'Logic' = 'Logic     '
      THEN
        DBMS_OUTPUT.put_line ('Equal');
      ELSE
        DBMS_OUTPUT.put_line ('Not Equal');
      END IF;
    END;
    

    显示Equal,因为“Logic”被空格填充到“Logic”

    【讨论】:

    • 我得出了同样的结论,但是 Oracle 文档中的引用呢?我只是误解了他们的意思还是要修复一个错误?
    • docs.oracle.com/cd/B14117_01/server.101/b10759/…Blank-Padded Comparison Semantics If the two values have different lengths, then Oracle first adds blanks to the end of the shorter one so their lengths are equal. .... Oracle uses blank-padded comparison semantics only when both values in the comparison are either expressions of datatype CHAR, NCHAR, text literals, ...
    • @are - 当您编写这样的查询时,begin - end 块是强制性的吗?在 sql server 中你不需要这个,但在 oracle 中我发现没有它就无法工作。
    • @FrenkyB 这是匿名块。该结构在许多数据库语言中很常见。我记得你在 MSSQL 脚本中跳过了开始...结束,但是如果你需要例如捕获异常,你将需要它与在 Oracle 中的方式相同
    猜你喜欢
    • 2011-11-09
    • 2017-11-13
    • 1970-01-01
    • 2015-06-17
    • 2012-06-12
    • 2022-01-25
    • 1970-01-01
    • 2015-11-19
    • 2011-09-12
    相关资源
    最近更新 更多