Oracle - 如何判断null和非null字符串?

时间:2017-02-03 18:51:39

标签: oracle plsql null oracle12c varchar2

在匿名块中,我有一个空/空的输入字符串,并希望针对非空字符串进行检查。示例:

StringBuilder

这里的问题是,当我运行此块时,输出始终为DECLARE v_notnull varchar2(50):='this string is never null'; v_input varchar2(50):=''; BEGIN IF trim(v_input) != trim(v_notnull) THEN dbms_output.put_line('the strings do NOT match'); ELSE dbms_output.put_line('the strings DO match'); END IF; END; ,即使我将空字符串'the strings DO match'(也称为null)输入到''中,而不是与字符串v_input相同。我怎样才能确保oracle覆盖空字符串的情况?当'this string is never null'为空时,我希望输出为v_input

3 个答案:

答案 0 :(得分:3)

documentation has a section on null handling。空字符串的处理方式与null相同,并且您无法将null(任何类型的)与等式进行比较 - 正如文档中的表所示,将任何与null进行比较的结果都是未知的 - 既不是true也不是false。您必须使用is [not] null将任何内容与null进行比较。

在这种情况下,您可以明确拼写出来,通过查看一个变量是null而另一个变量不是,反之亦然,并且只比较实际值,如果它们告诉您既不是null:

DECLARE 
v_notnull varchar2(30):='this string is never null';
v_input varchar2(30):='';
BEGIN
    IF (trim(v_input) is null and trim(v_notnull) is not null)
      or (trim(v_input) is not null and trim(v_notnull) is null)
      or trim(v_input) != trim(v_notnull) THEN
        dbms_output.put_line('the strings do NOT match');
    ELSE 
        dbms_output.put_line('the strings DO match');
    END IF;
END;
/

the strings do NOT match


PL/SQL procedure successfully completed.

我添加了缺少的varchar2尺寸;大概是你建立在一个程序上,这个程序在没有运行你单独发布的内容的情况下接受了争论......

答案 1 :(得分:2)

oracle中的{p> ''NULL。因此,任何与null的比较都将导致错误。

演示:

SQL> DECLARE
  2  v_notnull varchar2(1000):='this string is never null';
  3  v_input varchar2(1000):='';
  4  BEGIN
  5      IF v_input is null THEN
  6          dbms_output.put_line('v_input is null');   -- should print because v_input is actually null
  7      END IF;
  8
  9      IF trim(v_input) = trim(v_notnull) THEN        -- always false because of null
 10          dbms_output.put_line('the strings do NOT match');
 11      ELSE
 12          dbms_output.put_line('the strings DO match');  -- so should print this
 13      END IF;
 14  END;
 15  /
v_input is null            -- verified
the strings DO match       -- verified

PL/SQL procedure successfully completed.

SQL>

答案 2 :(得分:1)

通常你只关心值是否匹配,在这种情况下,空值没有区别:

declare
    v_notnull varchar2(50) := 'this string is never null';
    v_input   varchar2(50) := '';
begin
    if trim(v_input) = trim(v_notnull) then
        dbms_output.put_line('the strings DO match');
    else
        dbms_output.put_line('the strings do NOT match');
    end if;
end;

在某些情况下,您可以使用coalesce()nvl()表达式简化可空值的比较:

if nvl(v_yesno,'N') <> 'Y' then ...

您可能可以使用虚拟比较值(尽管当然存在与实际值匹配的风险,具体取决于具体情况):

if nvl(somevalue, chr(0)) <> nvl(othervalue, chr(0)) then ...

顺便说一句,您可以通过将值复制到null变量来区分''char,因为''会触发其通常无用的空白填充行为。我无法想到这会有用的情况,但只是为了好玩:

declare 
    v1 varchar2(1) := null;
    v2 varchar2(1) := '';

    c char(1);
begin
    c := v1;
    if v1 is null and c is not null then
        dbms_output.put_line('v1 = ''''');
    elsif c is null then
        dbms_output.put_line('v1 is null');
    end if;

    c := v2;
    if v2 is null and c is not null then
        dbms_output.put_line('v2 = ''''');
    elsif c is null then
        dbms_output.put_line('v2 is null');
    end if;

end;

输出:

v1 is null
v2 = ''