Oracle没有重置/重新初始化包

时间:2018-02-23 08:43:04

标签: oracle plsql

我有以下示例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

为什么“init called”在表中没有两次特色?是否有替代方案可以重置并重新初始化包?

修改

从@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;

1 个答案:

答案 0 :(得分:0)

  

重置后 - 包应该重新初始化吗?

到目前为止,我可以理解您的问题,如果您希望重新定位您的pacakge,则可能需要dbms_session.reinitialize代替dbms_session.reset_packageReinitializationRESETING不同。重新初始化是指将所有包变量重置为其初始值并在包体中运行初始化块(如果有)的过程,其中RESET_PACKAGE仅在PL / SQL调用之后释放内存,游标和包变量这使得调用完成了。

请参阅下面的重新初始化示例。

create or replace package P is
  cnt    number := 0;
  cursor c is select * from emp;
  procedure print_status;
end P;
/

create or replace package body P is
  procedure print_status is
  begin
    dbms_output.put_line('P.cnt = ' || cnt);
    if c%ISOPEN then
      dbms_output.put_line('P.c is OPEN');
    else
      dbms_output.put_line('P.c is CLOSED');
    end if;
  end;
end P;
/

SQL> set serveroutput on;
SQL> begin
  2   P.cnt := 111;
  3   open p.c;
  4   P.print_status;
  5  end;
  6  /
P.cnt = 111
P.c is OPEN

PL/SQL procedure successfully completed.

SQL> begin
  2   dbms_session.modify_package_state(dbms_session.reinitialize);
  3  end;
  4  /

PL/SQL procedure successfully completed.

SQL> set serveroutput on;
SQL>
SQL> begin
  2   P.print_status;
  3  end;
  4  /
P.cnt = 0
P.c is CLOSED

PL/SQL procedure successfully completed.