我在SQLDeveloper中遇到了一个奇怪的问题。
我有一个正常的select语句,如:SELECT COUNT(*) FROM demo WHERE NAME='ABC';
上面的查询给出了结果1。
运行与SELECT COUNT(*) FROM demo WHERE NAME='ABC ';
中相同的选择查询也会得到结果1。请注意,第二个查询中的额外附加空格不会更改计数值。
现在,在触发器中使用count(*)语句会产生不同的计数结果,并且在计算计数时会考虑空格。 为什么会发生这种情况?我使用的是SQLDeveloper版本4.1.5.21。
答案 0 :(得分:1)
如果您的专栏是char
而非varchar2
:
create table demo (name char(9));
insert into demo values ('ABC');
1 row inserted.
SELECT COUNT(*) FROM demo WHERE NAME='ABC';
COUNT(*)
----------
1
SELECT COUNT(*) FROM demo WHERE NAME='ABC ';
COUNT(*)
----------
1
如果您使用相同的文本文字在触发器或任何PL / SQL块中执行完全相同的查询,则会得到相同的结果:
set serveroutput on
declare
n number;
begin
SELECT COUNT(*) into n FROM demo WHERE NAME='ABC';
dbms_output.put_line(n);
SELECT COUNT(*) into n FROM demo WHERE NAME='ABC ';
dbms_output.put_line(n);
end;
/
1
1
PL/SQL procedure successfully completed.
但是如果您使用varchar2
变量来提供值而不是文本文字,则会得到不同的计数:
declare
n number;
v varchar2(9);
begin
v := 'ABC';
SELECT COUNT(*) into n FROM demo WHERE NAME=v;
dbms_output.put_line(n);
v := 'ABC ';
SELECT COUNT(*) into n FROM demo WHERE NAME=v;
dbms_output.put_line(n);
end;
/
0
1
PL/SQL procedure successfully completed.
使用文字文字it is treated as a char
时:
- 在表达式和条件中,Oracle将文本文字视为具有数据类型CHAR,方法是使用空白填充比较语义对它们进行比较。
然后明显的行为差异归结为blank-padded and nonpadded comparison semantics:
使用空白填充语义,如果两个值具有不同的长度,则Oracle首先将空白添加到较短值的末尾,因此它们的长度相等。
...
只要比较中的一个或两个值具有数据类型VARCHAR2或NVARCHAR2,Oracle就会使用非填充比较语义。
当您将char
列与(char
)文字文字进行比较时,两者都会填充到相同的长度,因此两个条件都会评估为真。使用空白填充语义,'ABC'
,'ABC '
,'ABC '
等等都是等效的。
当您将char
列与varchar2
变量进行比较时,不会发生填充,因此只有第二个条件(手动填充到与实际列值完全相同的长度)才会计算为true。填充列值'ABC '
仅在变量显式设置为完全相同时才匹配变量。它不等于'ABC'
或其他任何内容。
将varchar2
用于文本列通常要简单得多,以避免这些奇怪之处。不管怎样(根据我的经验)需要使用固定长度的字符串,如果数据的长度会有所不同,那么varchar2
会更灵活,并且会占用更少的存储空间。