|
Re: Initialisation of private variable [message #609718 is a reply to message #609715] |
Tue, 11 March 2014 08:21 |
ThomasG
Messages: 3211 Registered: April 2005 Location: Heilbronn, Germany
|
Senior Member |
|
|
There seems to be some ways to initialize the entire package (or to be exact *all* packages that are loaded at that point) again, mentioned on this page.
But that that also has other side effects, like losing the dbms_output lines for example.
|
|
|
Re: Initialisation of private variable [message #609719 is a reply to message #609718] |
Tue, 11 March 2014 08:27 |
|
ibergo
Messages: 18 Registered: February 2014
|
Junior Member |
|
|
Hmmm.
I tried both dbms_session.reset_package; and dbms_session.modify_package_state(dbms_session.reinitialize);, but none of them have the desired effect in the context of a loop in a single anonymous block...
And the recompilation of the package causes a ddl lock. So that doesn't work neither.
[Updated on: Tue, 11 March 2014 08:47] Report message to a moderator
|
|
|
Re: Initialisation of private variable [message #609722 is a reply to message #609719] |
Tue, 11 March 2014 08:50 |
Solomon Yakobson
Messages: 3273 Registered: January 2010 Location: Connecticut, USA
|
Senior Member |
|
|
ibergo wrote on Tue, 11 March 2014 09:27Hmmm.
I tried both dbms_session.reset_package; and dbms_session.modify_package_state(dbms_session.reinitialize);, but none of them have the desired effect in the context of a loop in a single anonymous block...
SCOTT@orcl > create or replace package foo_pck is
2 procedure foo_count;
3 end;
4 /
Package created.
SCOTT@orcl > create or replace package body foo_pck is
2 v_count number := 0;
3 procedure foo_count is
4 begin
5 dbms_output.put_line('BEFORE v_count='||v_count);
6 v_count := v_count + 1;
7 dbms_output.put_line('AFTER v_count='||v_count);
8 end;
9 end;
10 /
Package body created.
SCOTT@orcl > exec dbms_session.reset_package
PL/SQL procedure successfully completed.
SCOTT@orcl > set serveroutput on
SCOTT@orcl > begin
2 dbms_output.enable;
3 foo_pck.foo_count;
4 end;
5 /
BEFORE v_count=0
AFTER v_count=1
PL/SQL procedure successfully completed.
SCOTT@orcl > exec dbms_session.reset_package
PL/SQL procedure successfully completed.
SCOTT@orcl > set serveroutput on
SCOTT@orcl > begin
2 dbms_output.enable;
3 foo_pck.foo_count;
4 end;
5 /
BEFORE v_count=0
AFTER v_count=1
PL/SQL procedure successfully completed.
SCOTT@orcl > exec dbms_session.reset_package
PL/SQL procedure successfully completed.
SCOTT@orcl > set serveroutput on
SCOTT@orcl > begin
2 dbms_output.enable;
3 foo_pck.foo_count;
4 end;
5 /
BEFORE v_count=0
AFTER v_count=1
PL/SQL procedure successfully completed.
SCOTT@orcl >
However using dbms_session.reset_package isn't good solution - it resets ALL session packages.
SY.
|
|
|
|
Re: Initialisation of private variable [message #609725 is a reply to message #609724] |
Tue, 11 March 2014 09:13 |
Solomon Yakobson
Messages: 3273 Registered: January 2010 Location: Connecticut, USA
|
Senior Member |
|
|
Well, you can do that inside the loop - no diff. However reset package will, as I already mentioned, reset package will reset all session packages including DBMS_OUTPUT, so you'll lose the output. So I added get_count function to the package just to show v_count value:
SCOTT@orcl > drop package foo_pck
2 /
Package dropped.
SCOTT@orcl > create or replace package foo_pck is
2 procedure foo_count;
3 function get_count return number;
4 end;
5 /
Package created.
SCOTT@orcl > create or replace package body foo_pck is
2 v_count number := 0;
3 procedure foo_count is
4 begin
5 dbms_output.put_line('BEFORE v_count='||v_count);
6 v_count := v_count + 1;
7 dbms_output.put_line('AFTER v_count='||v_count);
8 end;
9 function get_count return number
10 is
11 begin
12 return v_count;
13 end;
14 end;
15 /
Package body created.
SCOTT@orcl > set serveroutput on
SCOTT@orcl > begin
2 for i in 1..3 loop
3 dbms_output.put_line('Run '||i);
4 foo_pck.foo_count;
5 dbms_session.reset_package;
6 end loop;
7 end;
8 /
PL/SQL procedure successfully completed.
SCOTT@orcl > set serveroutput on
SCOTT@orcl > exec dbms_output.put_line(foo_pck.get_count)
0
PL/SQL procedure successfully completed.
SCOTT@orcl >
SY.
|
|
|
|
|
|
|
|
|
|
|
Re: Initialisation of private variable [message #609781 is a reply to message #609778] |
Wed, 12 March 2014 04:31 |
ThomasG
Messages: 3211 Registered: April 2005 Location: Heilbronn, Germany
|
Senior Member |
|
|
Depending on how often the procedure needs to be called in what way it might even be an option to write the (OS) scripts in a way that they connect, run the procedure once, and then disconnect again.
|
|
|
Re: Initialisation of private variable [message #609783 is a reply to message #609781] |
Wed, 12 March 2014 04:45 |
|
ibergo
Messages: 18 Registered: February 2014
|
Junior Member |
|
|
I consider recommending to test a similar solution: Let the original loop run, but instead of letting it start the problematic procedure, let it write text in terms of new anonymous pl/sql blocks (including calls to dbms_session.reset_package) to a new temporary script, and run that script afterwards.
I think that ought to work (havn't testet yet), but it of course might introduce performance issues. The question is just how big they will end up to be. The real world context is a batch program, that loops through "some" thousands of records, and runs for 5-6 hours once or twice a year. Next time is in the end of the month, which is why we don't have too much time to do a real code fix.
|
|
|