用pl/sql developer测一段pl/sql代码1. 编译我的pl/sql代码
2. 运行测试程序,得到预期结果。而且我的pl/sql代码中的dbms_output.put_line的输出也会正确显示
3. 然后在不重新编译我的pl/sql代码的前提下,重新运行测试程序(非debug方式),返回结果就不同了,而且dbms_output.put_line的输出没有显示。无论多少遍都是一样但是如果重新编译pl/sql代码或者以debug方式运行,返回值就总是一致的,而且dbms_output.put_line的输出正确显示加了PRAGMA SERIALLY_REUSABLE之后,就不会出现这个现象了,但是我还是有一点不明白,包变量是session级别的,被缓存了可以理解,但是就算是被缓存了,为什么dbms_output的输出为什么没有了呢,而且好像子函数也没有执行(直接就返回了true)。这是怎么回事啊
2. 运行测试程序,得到预期结果。而且我的pl/sql代码中的dbms_output.put_line的输出也会正确显示
3. 然后在不重新编译我的pl/sql代码的前提下,重新运行测试程序(非debug方式),返回结果就不同了,而且dbms_output.put_line的输出没有显示。无论多少遍都是一样但是如果重新编译pl/sql代码或者以debug方式运行,返回值就总是一致的,而且dbms_output.put_line的输出正确显示加了PRAGMA SERIALLY_REUSABLE之后,就不会出现这个现象了,但是我还是有一点不明白,包变量是session级别的,被缓存了可以理解,但是就算是被缓存了,为什么dbms_output的输出为什么没有了呢,而且好像子函数也没有执行(直接就返回了true)。这是怎么回事啊
i number;
j varchar2(20);
begin
srPkg1.initialize;---给全局变量赋值
i:=srPkg1.return_num;--返回全局变量
j:=srPkg1.return_char;--返回全局变量
dbms_output.put_line(to_char(i));
dbms_output.put_line(j);
end;declare
i number;
j varchar2(20);
begin
i:=srPkg1.return_num;
j:=srPkg1.return_char;
dbms_output.put_line(to_char(i));
dbms_output.put_line(j);
end;这就说明了pragma serially_reusable对包全局变量,游标的影响。
你给出的这个例子,我是这么理解的,如果没有pragma serially_reusable的话,那么只要运行过第一个,那么包srPkg1的全局变量就被初始化了,那么以后就算是运行第二个(即没有调用srPkg1.initialize)也会有输出,这我可以理解,因为包全局变量是session级别的。举个例子吧
create or replace package body testSerially_reusable is
type type_array is table of varchar(20);
records type_array; procedure initialize is
begin
records.extend;
records(records.last) := to_char(records.last);
end; function return_num return number is
begin
return records.count;
end; function checknum return boolean is
num number;
begin
for i in records.first .. records.last loop
num := to_number(records(i));
if num >= 1 then
return false;
end if;
return true;
end loop;
end; function return_char return varchar2 is
total varchar2(2000) := '';
begin
if checknum then
for i in records.first .. records.last loop
total := total || records(i) || ' ';
end loop;
return total;
else
return 'too much';
end if;
end;begin
if records is null then
records := type_array();
else
records.delete;
end if;
end testSerially_reusable;上面这个函数,我在return_char首先调用了checknum,由于num >= 1的判断条件,第一运行就会输出
1
more than 5
以后再运行,就一次输出
2
more than 5
3
more than 5
等等如果我把判断条件换成num >= 3,那么问题就出现了
连续运行的结果是
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
1 2 3 4 5
等等
也就是说看起来就是checknum总是返回true,难道第一次checknum运行的结果被缓存了?