Oracle - 如何区分空字符串和非空字符串?
Oracle - How to tell between null and not null string?
在一个匿名块中,我有一个输入字符串 empty/null 并且想根据非空字符串检查它。示例:
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'
即使我输入空字符串 ''
(又名空)到 v_input
与字符串 'this string is never null'
不同。我怎样才能确保 oracle 涵盖空字符串的情况?当 v_input
为空时,我希望输出为 'the strings do NOT match'
.
documentation has a section on null handling。空字符串被视为与 null 相同,并且您不能将(任何类型的)null 与相等性进行比较 - 正如文档中的 table 所示,将任何内容与 null 进行比较的结果是未知的 - 既不是真也不是假。您必须使用 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
尺寸;大概你是基于一个没有 运行 你发布的内容的参数的过程 stand-alone...
''
在 Oracle 中是 NULL
。因此,与 null 的任何比较都将始终返回 false。
演示:
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>
通常您只关心值是否匹配,在这种情况下,空值没有区别:
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 ...
顺便说一下,您可以通过将值复制到 char
变量来区分 null
和 ''
,因为 ''
会触发它通常无用的 blank-padding行为。我真的想不出这在什么情况下会有用,但只是为了好玩:
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 = ''
在一个匿名块中,我有一个输入字符串 empty/null 并且想根据非空字符串检查它。示例:
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'
即使我输入空字符串 ''
(又名空)到 v_input
与字符串 'this string is never null'
不同。我怎样才能确保 oracle 涵盖空字符串的情况?当 v_input
为空时,我希望输出为 'the strings do NOT match'
.
documentation has a section on null handling。空字符串被视为与 null 相同,并且您不能将(任何类型的)null 与相等性进行比较 - 正如文档中的 table 所示,将任何内容与 null 进行比较的结果是未知的 - 既不是真也不是假。您必须使用 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
尺寸;大概你是基于一个没有 运行 你发布的内容的参数的过程 stand-alone...
''
在 Oracle 中是 NULL
。因此,与 null 的任何比较都将始终返回 false。
演示:
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>
通常您只关心值是否匹配,在这种情况下,空值没有区别:
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 ...
顺便说一下,您可以通过将值复制到 char
变量来区分 null
和 ''
,因为 ''
会触发它通常无用的 blank-padding行为。我真的想不出这在什么情况下会有用,但只是为了好玩:
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 = ''