【发布时间】:2018-02-23 22:03:51
【问题描述】:
我有以下示例 PL/SQL 代码:
create table messages
(
when timestamp,
what varchar2(200)
)
create or replace package init_test
is
procedure set(
w varchar2
);
procedure report(
msg varchar2
);
end;
create or replace package body init_test
is
wibble varchar2(100);
procedure set(
w varchar2
) is
begin
wibble := w;
report('Setting ' || w);
end;
procedure report(
msg varchar2
) is
pragma AUTONOMOUS_TRANSACTION;
begin
insert into messages values(current_timestamp, 'Wibble := ' || wibble);
insert into messages values(current_timestamp, msg);
commit;
end;
begin
report('Init called');
end; -- End of package body
begin
init_test.set('Init test');
init_test.report('Hello world');
dbms_session.reset_package;
init_test.report('Goodbye world');
end;
/
运行后,messages 包含:
23-FEB-18 08.23.24.439726000 Wibble :=
23-FEB-18 08.23.24.440028000 Init called
23-FEB-18 08.23.24.440267000 Wibble := Init test
23-FEB-18 08.23.24.440435000 Setting Init test
23-FEB-18 08.23.24.440597000 Wibble := Init test
23-FEB-18 08.23.24.440747000 Hello world
23-FEB-18 08.23.24.440947000 Wibble := Init test
23-FEB-18 08.23.24.441098000 Goodbye world
为什么“初始化调用”没有在表中出现两次?是否有替代方案可以重置并重新初始化包?
编辑
来自@XING 的回答 - 我尝试了以下方法 - 但仍然存在同样的问题。
create table messages
(
when timestamp,
what varchar2(200)
)
create or replace package P is
cnt number := 0;
cursor c is select * from all_objects;
procedure print_status;
procedure report(
msg varchar2
);
end P;
/
create or replace package body P is
procedure report(
msg varchar2
) is
pragma AUTONOMOUS_TRANSACTION;
begin
insert into messages values(current_timestamp, msg);
commit;
end;
procedure print_status is
begin
report('P.cnt = ' || cnt);
if c%ISOPEN then
report('P.c is OPEN');
else
report('P.c is CLOSED');
end if;
end;
end P;
/
begin
P.cnt := 111;
open p.c;
P.print_status;
dbms_session.modify_package_state(dbms_session.reinitialize);
P.print_status;
end;
【问题讨论】:
-
你的包裹体的末端在哪里?我在您的代码中找不到它。你能放吗?我也无法理解为什么你在执行一次时会期望“调用 init”两次。
-
重置后 - 包应该重新初始化吗?
-
是的,在
dbms_session.reset_package之后,此会话中的所有包都将被取消实例化。当你说去实例化意味着它只在使调用完成运行的 PL/SQL 调用之后释放内存、游标和包变量。要重新初始化变量,您可能需要使用DBMS_SESSION.REINITIALIZE