PRAGMA SERIALLY_REUSABLE for Package

1) PRAGMA SERIALLY_REUSABLE for Package
1@@@@Serializable Packages (PRAGMA SERIALLY_REUSABLE)
  As you have seen, package data by default persists for your entire session (or until the
  package is recompiled). This is an incredibly handy feature, but it has some drawbacks:
  ~ Globally accessible (public and private) data structures persist, and that can cause
    undesired side effects. In particular, I can inadvertently leave packaged cursors
    open, causing ¡°already openâ?? errors in other programs.
  ~ My programs can suck up lots of real memory (package data is managed in the
    user¡¯s memory area or User Global Area [UGA]) and then not release it if that data
    is stored in a package-level structure.

  To help you manage the use of memory in packages, PL/SQL offers the
  SERIALLY_REUSABLE pragma. This pragma, which must appear in both the package
  specification and the body (if one exists), marks that package as serially reusable. For
  such packages, the duration of package state (the values of variables, the open status
  of a packaged cursor, etc.) can be reduced from a whole session to a single call of a
  program in the package.

   @@@Example01: Test with PRAGMA SERIALLY_REUSABLE
    SYS@ocm> !cat tmp.sql
    DROP TABLE books
    /
    CREATE TABLE books
        (  author      VARCHAR2(100)
         , title       VARCHAR2(250)
         , page_count  NUMBER(5) 
         , CONSTRAINT pk_books PRIMARY KEY (author, title) )
    /
    BEGIN
       DELETE FROM books;
       INSERT INTO books VALUES('fatpander_small_one','Pander Trveral', 100);
       INSERT INTO books VALUES('fatpander_big_one','Pander Trveral', 100);
       COMMIT;
    END;
    /
    CREATE OR REPLACE PACKAGE book_info
    IS
        PRAGMA SERIALLY_REUSABLE;
       
        PROCEDURE fill_list;
       
        PROCEDURE show_list;
    END;
    /
    CREATE OR REPLACE PACKAGE BODY book_info
    IS
        PRAGMA SERIALLY_REUSABLE;
       
        TYPE book_list_aat IS TABLE OF books%ROWTYPE
           INDEX BY PLS_INTEGER;
        my_books_aa  book_list_aat;
   
        PROCEDURE fill_list
        IS
        BEGIN
           FOR rec IN (SELECT *
                         FROM books
                        WHERE author LIKE '%big%')
           LOOP
              my_books_aa (my_books_aa.COUNT+1) := rec;
           END LOOP;
        END fill_list;
   
        PROCEDURE show_list
        IS
        BEGIN
           IF my_books_aa.COUNT = 0
           THEN
              DBMS_OUTPUT.put_line('** Associate array my_books_at is empty');
           ELSE
              FOR i IN 1 .. my_books_aa.COUNT
              LOOP
                 DBMS_OUTPUT.put_line( my_books_aa(i).title );
              END LOOP;
           END IF;
        END;
   
    END;
    /
    SYS@ocm> @tmp.sql
    Table dropped.
    Table created.
    PL/SQL procedure successfully completed.
    Package created.
    Package body created.
    SYS@ocm>
   
   @@@ Begin to test, run the package procedure together
    SYS@ocm> !cat test_together.sql
    BEGIN
       DBMS_OUTPUT.put_line('Fill and show in same block:');
       book_info.fill_list;
       book_info.show_list;
    END;
    /
    SYS@ocm> @test_together.sql
    Fill and show in same block:
    Pander Trveral   ------------Here exist
    PL/SQL procedure successfully completed.
       
   @@@ Begin to test, run the package procedure seprately
    SYS@ocm> !cat test_seprate01.sql
    BEGIN
       DBMS_OUTPUT.put_line('Fill in first block');
       book_info.fill_list;
    END;
    /
   
    SYS@ocm> !cat test_seprate02.sql
    BEGIN
       DBMS_OUTPUT.put_line('Show in seond block');
       book_info.show_list;
    END;
    /
    SYS@ocm> @test_seprate01.sql
    Fill in first block
    PL/SQL procedure successfully completed.
   
    SYS@ocm> @test_seprate02.sql
    Show in seond block
    ** Associate array my_books_at is empty -----Not exist
    PL/SQL procedure successfully completed.


   
  @@@Versus Example01 and Example02
  @@@Example02: Test without PRAGMA SERIALLY_REUSABLE   
    CREATE OR REPLACE PACKAGE book_info
    IS
        PROCEDURE fill_list;
       
        PROCEDURE show_list;
    END;
    /
    CREATE OR REPLACE PACKAGE BODY book_info
    IS
        TYPE book_list_aat IS TABLE OF books%ROWTYPE
           INDEX BY PLS_INTEGER;
        my_books_aa  book_list_aat;
   
        PROCEDURE fill_list
        IS
        BEGIN
           FOR rec IN (SELECT *
                         FROM books
                        WHERE author LIKE '%big%')
           LOOP
              my_books_aa (my_books_aa.COUNT+1) := rec;
           END LOOP;
        END fill_list;
   
        PROCEDURE show_list
        IS
        BEGIN
           IF my_books_aa.COUNT = 0
           THEN
              DBMS_OUTPUT.put_line('** Associate array my_books_at is empty');
           ELSE
              FOR i IN 1 .. my_books_aa.COUNT
              LOOP
                 DBMS_OUTPUT.put_line( my_books_aa(i).title );
              END LOOP;
           END IF;
        END;
   
    END;
    /
   @@@Test code the same above Example01
    SYS@ocm> @test_together.sql
    Fill and show in same block:
    Pander Trveral
    PL/SQL procedure successfully completed.   
   
    SYS@ocm> @test_seprate01.sql
    Fill in first block
    PL/SQL procedure successfully completed.
   
    SYS@ocm> @test_seprate02.sql
    Show in seond block
    Pander Trveral   ------------------Here Exist
    Pander Trveral   ------------------Here Exist
    PL/SQL procedure successfully completed.

   @@@Summary: package with PRAGMA SERIALLY_REUSABLE could save memory.


  Here are some things to keep in mind for serialized packages:
  ~ The global memory for serialized packages is allocated in the SGA, not in the user¡¯s
    UGA. This approach allows the package work area to be reused. Each time the
    package is reused, its package-level variables are initialized to their default values
    or to NULL, and its initialization section is re-executed.
  ~ The maximum number of work areas needed for a serialized package is the number
    of concurrent users of that package. The increased use of SGA memory is offset by
    the decreased use of UGA or program memory. Finally, the database ages out work
    areas not in use if it needs to reclaim memory from the SGA for other requests.


referencing "Oracle PL/SQL Program Design 5th Edition"

你可能感兴趣的:(pragma)