我试图找到检查CHAR/VARCHAR2
变量是否包含字符的最佳方法(NULL
或空格应视为相同,如“无值”:]
我知道有几种解决方案,但看来(NVL(LENGTH(TRIM(v)),0) > 0)
比(v IS NOT NULL AND v != ' ')
快
知道为什么吗?还是我在测试代码中做错了什么?
[在Linux上用Oracle 18c
测试,UTF-8 db charset
...
我得到以下结果:
时间:+000000000 00:00:03.582731000
时间:+000000000 00:00:02.494980000
set serveroutput on;
create or replace procedure test1
is
ts timestamp(3);
x integer;
y integer;
v char(500);
--v varchar2(500);
begin
ts := systimestamp;
--v := null;
v := 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
for x in 1..50000000
loop
if v is not null and v != ' ' then
y := x;
end if;
end loop;
dbms_output.put_line('time:' || (systimestamp - ts) ) ;
end;
/
create or replace procedure test2
is
ts timestamp(3);
x integer;
y integer;
v char(500);
--v varchar2(500);
begin
ts := systimestamp;
--v := null;
v := 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
for x in 1..50000000
loop
if nvl(length(trim(v)),0) > 0 then
y := x;
end if;
end loop;
dbms_output.put_line('time:' || (systimestamp - ts) ) ;
end;
/
begin
test1();
test2();
end;
/
drop procedure test1;
drop procedure test2;
quit;
最佳实践是忽略小功能之间的速度差异,并使用最简单的方法。
[在实际的数据库编程中,与从磁盘读取数据所需的时间或联接数据所需的时间相比,运行NVL
或IS NOT NULL
之类的功能所需的时间完全无关紧要。如果一个功能每5000万行节省1秒,那么没人会注意到。而如果一条SQL语句使用全表扫描读取5000万行而不是使用索引,反之亦然,则可能会完全破坏应用程序。
在数据库中关心这类问题是不寻常的。 (但并非不可能-如果您有特定的用例,请将其添加到问题中。)如果您确实需要最佳的过程代码,则可以考虑使用Java或C编写外部过程。