編譯指令PRAGMA SERIALLY_REUSABLE

franklynzhou發表於2010-08-22

當對包進行第一次例項的時候,將從磁碟讀入該包的中間程式碼並將其放入系統全域性工作區SGA的共享緩衝區中。然而,包的執行狀態,即打包的變數和遊標,將存放在使用者全域性區(UGA)的會話儲存區中。這就保證了每個會話都將有其自己的包執行狀態的副本。在包頭包括在包體的首部宣告的變數與遊標的作用域為全域性範圍,這些變數對於具有EXECUTE 特權的任何PL/SQL塊都是可見的。由於包的執行狀態時在UGA中存放的,所以他們有與資料庫會話相同的生命期。當包被例項時,其執行狀態也得到初始化,並且這些狀態直到會話結束才被釋放。即使包本身由於超時被從共享緩衝區中刪除,但該包的狀態仍然保持。

[@more@]

一、建立普通的包

CREATE OR REPLACE PACKAGE pkg_test IS

TYPE t_tbls IS TABLE OF VARCHAR2(100);

t_tbl t_tbls;

PROCEDURE up_init;

END;

/

CREATE OR REPLACE PACKAGE BODY pkg_test IS

PROCEDURE up_init IS

BEGIN

IF t_tbl IS NULL THEN

t_tbl := t_tbls();

END IF;

t_tbl.extend;

t_tbl(t_tbl.count) := t_tbl.count;

dbms_output.put_line('up_init:' || t_tbl.count);

END;

END;

/

二、包內變數的變化:

SQL> set serveroutput on

SQL>

SQL> DECLARE

2 t_tbl pkg_test.t_tbls := pkg_test.t_tbls();

3 BEGIN

4 pkg_test.up_init;

5 t_tbl := pkg_test.t_tbl;

6 dbms_output.put_line(t_tbl.count);

7 END;

8 /

up_init:1

1

PL/SQL procedure successfully completed

SQL>

SQL> DECLARE

2 t_tbl pkg_test.t_tbls := pkg_test.t_tbls();

3 BEGIN

4 pkg_test.up_init;

5 t_tbl := pkg_test.t_tbl;

6 dbms_output.put_line(t_tbl.count);

7 END;

8 /

up_init:2

2

PL/SQL procedure successfully completed

SQL> alter system flush shared_pool;

System altered

SQL>

SQL> DECLARE

2 t_tbl pkg_test.t_tbls := pkg_test.t_tbls();

3 BEGIN

4 pkg_test.up_init;

5 t_tbl := pkg_test.t_tbl;

6 dbms_output.put_line(t_tbl.count);

7 END;

8 /

up_init:3

3

PL/SQL procedure successfully completed

SQL>

SQL> disc

Not logged on

SQL> conn dbo/dbo

Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.3.0

Connected as DBO

SQL> set serveroutput on

SQL>

SQL> DECLARE

2 t_tbl pkg_test.t_tbls := pkg_test.t_tbls();

3 BEGIN

4 pkg_test.up_init;

5 t_tbl := pkg_test.t_tbl;

6 dbms_output.put_line(t_tbl.count);

7 END;

8 /

up_init:1

1

PL/SQL procedure successfully completed

SQL>

經過以上測試發現,就算是清除共享區,包中的變數什依然沒有被重置,只有會話斷掉才會被重置。

三、建立PRAGMA SERIALLY_REUSABLE

CREATE OR REPLACE PACKAGE pkg_test IS PRAGMA SERIALLY_REUSABLE;

TYPE t_tbls IS TABLE OF VARCHAR2(100);

t_tbl t_tbls;

PROCEDURE up_init;

END;

/

CREATE OR REPLACE PACKAGE BODY pkg_test IS PRAGMA SERIALLY_REUSABLE;

PROCEDURE up_init IS

BEGIN

IF t_tbl IS NULL THEN

t_tbl := t_tbls();

END IF;

t_tbl.extend;

t_tbl(t_tbl.count) := t_tbl.count;

dbms_output.put_line('up_init:' || t_tbl.count);

END;

END;

/

四、包內變數的變化

SQL> set serveroutput on

SQL>

SQL> DECLARE

2 t_tbl pkg_test.t_tbls := pkg_test.t_tbls();

3 BEGIN

4 pkg_test.up_init;

5 t_tbl := pkg_test.t_tbl;

6 dbms_output.put_line(t_tbl.count);

7 END;

8 /

up_init:1

1

PL/SQL procedure successfully completed

SQL>

SQL> DECLARE

2 t_tbl pkg_test.t_tbls := pkg_test.t_tbls();

3 BEGIN

4 pkg_test.up_init;

5 t_tbl := pkg_test.t_tbl;

6 dbms_output.put_line(t_tbl.count);

7 END;

8 /

up_init:1

1

PL/SQL procedure successfully completed

SQL>

五、可連續重用包與非連續重用包的區別

執行狀態儲存在SGA中,每次資料庫呼叫後都將該執行狀態釋放,所用的最大記憶體與包的併發使用者數量成正比。後者執行狀態儲存在UGA中,其生存期與資料庫會話相同,所用最大記憶體數與當前登入的使用者數目成正比

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10455206/viewspace-1037204/,如需轉載,請註明出處,否則將追究法律責任。

相關文章