Cursors in package

I want to know what is faster if a definition of a cursor is declared in a package or if a cursor id declared in the same procedure where it is going to be used ?
What advantadges and disadvantages it has ?
Thanks for all
Joel P�rez

There is just a bit more to your question than just the time it takes to create/open a cursor. The biggest time lag will be any SQL*NET conversation from your client to your database. If the cursor is defined in a package on the server then it is compiled at creation time.
If the cursor is defined in a procedure on the client side then procedure has to be passed to the database then be compiled and then run. This is a substancially slower process in the millisecond world.
Hope this helps!

Similar Messages

  • Can we declare a Cursor in Package Specs?

    Dear buddies
    Can I Declare a Cursor in Package Specs so that I can call that cursor and use its data in some procedures and functions of package. Otherwise I've to write that cursor for every sub-program of a package which I don't feel a smart way to accomplish the job.

    Hi,
    here is a short example with the whole way down. Maybe the concept is getting clearer with this:
    first of all, if you do not have the table emp, here the DDL for this example.
    Be carefull, works only for german clients because of the names of months, sorry for that.
    CREATE TABLE EMP
    (EMPNO NUMBER(4) NOT NULL,
    ENAME VARCHAR2(10),
    JOB VARCHAR2(9),
    MGR NUMBER(4),
    HIREDATE DATE,
    SAL NUMBER(7, 2),
    COMM NUMBER(7, 2),
    DEPTNO NUMBER(2));
    set echo on
    INSERT INTO EMP VALUES
    (7369, 'SMITH', 'CLERK', 7902,
    TO_DATE('17-DEZ-1980', 'DD-MON-YYYY'), 800, NULL, 20);
    INSERT INTO EMP VALUES
    (7499, 'ALLEN', 'SALESMAN', 7698,
    TO_DATE('20-FEB-1981', 'DD-MON-YYYY'), 1600, 300, 30);
    INSERT INTO EMP VALUES
    (7521, 'WARD', 'SALESMAN', 7698,
    TO_DATE('22-FEB-1981', 'DD-MON-YYYY'), 1250, 500, 30);
    INSERT INTO EMP VALUES
    (7566, 'JONES', 'MANAGER', 7839,
    TO_DATE('2-APR-1981', 'DD-MON-YYYY'), 2975, NULL, 20);
    INSERT INTO EMP VALUES
    (7654, 'MARTIN', 'SALESMAN', 7698,
    TO_DATE('28-SEP-1981', 'DD-MON-YYYY'), 1250, 1400, 30);
    INSERT INTO EMP VALUES
    (7698, 'BLAKE', 'MANAGER', 7839,
    TO_DATE('1-MAI-1981', 'DD-MON-YYYY'), 2850, NULL, 30);
    INSERT INTO EMP VALUES
    (7782, 'CLARK', 'MANAGER', 7839,
    TO_DATE('9-JUN-1981', 'DD-MON-YYYY'), 2450, NULL, 10);
    INSERT INTO EMP VALUES
    (7788, 'SCOTT', 'ANALYST', 7566,
    TO_DATE('09-DEZ-1982', 'DD-MON-YYYY'), 3000, NULL, 20);
    INSERT INTO EMP VALUES
    (7839, 'KING', 'PRESIDENT', NULL,
    TO_DATE('17-NOV-1981', 'DD-MON-YYYY'), 5000, NULL, 10);
    INSERT INTO EMP VALUES
    (7844, 'TURNER', 'SALESMAN', 7698,
    TO_DATE('8-SEP-1981', 'DD-MON-YYYY'), 1500, 0, 30);
    INSERT INTO EMP VALUES
    (7876, 'ADAMS', 'CLERK', 7788,
    TO_DATE('12-JAN-1983', 'DD-MON-YYYY'), 1100, NULL, 20);
    INSERT INTO EMP VALUES
    (7900, 'JAMES', 'CLERK', 7698,
    TO_DATE('3-DEZ-1981', 'DD-MON-YYYY'), 950, NULL, 30);
    INSERT INTO EMP VALUES
    (7902, 'FORD', 'ANALYST', 7566,
    TO_DATE('3-DEZ-1981', 'DD-MON-YYYY'), 3000, NULL, 20);
    INSERT INTO EMP VALUES
    (7934, 'MILLER', 'CLERK', 7782,
    TO_DATE('23-JAN-1982', 'DD-MON-YYYY'), 1300, NULL, 10);2. Package Spec:
    create or replace
    package test_cursor as
      --Type for the returncode of the function
      TYPE typ_emp IS TABLE OF emp%rowtype;
      --Array for fetching, of course also possible in the body
      t_emp typ_emp;
      --function wich returns the array from fetching the cursor
      function get_emp return typ_emp;
      --function for manupilation data retrieved by the function
      PROCEDURE man_emp;
    end test_cursor;3. Package Body
    create or replace
    package body test_cursor as
      FUNCTION get_emp RETURN typ_emp AS
      cursor c_emp is select * from emp;
      BEGIN
        open c_emp;
        fetch c_emp BULK COLLECT INTO t_emp;
        CLOSE c_emp;
        --t_emp returns the whole table set from emp
        return t_emp;
      end get_emp;
      PROCEDURE man_emp AS
      --just for not confusing names, is the same as t_emp of course
      v_emp_array typ_emp;
      BEGIN
        --call the function and retrieve the whole data set
        v_emp_array := get_emp;
        --now manipulate the data, in this case just write the names to the calling client
        FOR rec IN v_emp_array.FIRST .. v_emp_array.LAST
        loop
          dbms_output.put_line(v_emp_array(rec).ename);
        end loop;
      end man_emp;
    end test_cursor;4. Calling the procedure
    SET serveroutput ON
    exec test_cursor.man_emp;5. And this is the result:
    anonymer Block abgeschlossen
    SMITH
    ALLEN
    WARD
    JONES
    MARTIN
    BLAKE
    CLARK
    SCOTT
    KING
    TURNER
    ADAMS
    JAMES
    FORD
    MILLERPlease be aware, this is just for demonstration purpose, of course it makes no sense to display the names this way. But how to call a funktion returning arrays with datasets from fetching cursors is shown here.
    Hth
    Joerg

  • Declaring private cursors in package header

    Hi.
    Im tunning a PLSQL package , and im having the following doubt.
    This package has alot of cursors declared in the package header, but the cursors are private. (called within the package only)
    Could the public functions from the package have a loss of performance by using those cursors? (should the private cursors be declared within the functions or at least inside package body?)
    Im kind of new with plsql, so please bare with me :) .
    Cheers.

    there's no performance loss.
    however, unless the cursors are to be accessible outside the package (which is what happens when they are declared in the spec (not header)), then there's no benefit either. if they are truely meant to be private, then you can remove them from the spec. and if you're wrong, and they are called from elsewhere, you'll find out soon enough.

  • Cursor in packages

    hi,
    what is the difference using cursor in body&specifications?  how do we separate both of them?
    regards
    kar

    1007109 wrote:
    for example their is 10 cursor in the package ....Is it possible to pass a different input value for each cursor???
    The cursor declarations are just that... declarations.  You can reuse the declarations multiple times, and if the cursor is parameterised it will work with whataver parameters are passed to it.
    The instantiation of the cursor happens when you open it directly using an open statement, or indirectly using a for loop etc.

  • Need you help !!! -- How to set PACKAGE SIZE in CURSOR?

    Dear experts:
    Does anybody know how to set the package size if you use cursor in your abap program?
    My scenario is to select all the data from MARA table in which the data volumn is very big, and then process for some specific logic. When I try to select them into one internal table or use CURSOR without package, my abap program will abort after running for around 1 hour. So I was thinking if I can use cursor and set the PACKAGE SIZE like 10,000 and process the data by batch.
    Here is my sample code:
    OPEN CURSOR: CUR_MARA_TBL FOR
    SELECT * FROM MARA.
    DO.
    FETCH NEXT CURSOR CUR_MARA_TBL INTO CORRESPONDING FIELDS OF WA_MARA_TBL.
    IF sy-subrc = 0.
    ......Detail logic......
    ENDIF.
    ENDDO.
    I would appreciate if anybody can let me know how to set the package size based on the sample code above, or any webpage/article about that.
    Any reply would be appreciated and thank you all in advance!
    Best Regards.
    Tim
    Moderator message: please study F1 help for FETCH statement.
    locked by: Thomas Zloch on Sep 8, 2010 4:10 PM

    The Spark List's layout property has the requestedRowCount and requestedMinRowCount properties.
    You can either set a new layout property on your List like this:
    <s:List>
            <s:layout>
                <s:VerticalLayout requestedMinRowCount="1" />
            </s:layout>
        </s:List>
    or reskin the List and modify the VerticalLayout in your copy of ListSkin.
    Jason

  • Cannot figure out why "ORA-01000 Maximum open cursors" is shown...

    Hello there ...
    I am programming a PL/SQL Code that is throwing 0RA-01000 Maximum Open Cursors Exceeded.
    Having already read quite a lot about ORA-01000 errors, I know I should be closing cursors, and have already tried setting OPEN_CURSORS parameter to a high number (1000).
    I declared a lot of procedures in my pl/sql, each of which uses one cursor since i am working with a non-Oracle table linked by ODBC ... and each procedure sometimes does thousands of inserts -- but all WITHIN the explicit cursors. The explicit cursors are not declared within each loop.
    I already checked the code many times, and made sure all open cursors are closed. In addition, I also verified the numberopen cursors generated by the PL/SQL by running the following SQL after every procedure i run... and outputting it... and it appears the value just keeps on increasing, even though I had explicitly closed all the cursors in all the earlier procedures.
    What is funny is that the most number of cursors reported by the code below only hits 150+ cursors. Nowhere near the 1000 open_cursors limit per session.
    select a.value into strtxt --, b.name        
            from v$mystat a, v$statname b
            where a.statistic# = b.statistic#
            and a.statistic#= 3;When I run the procedures separately though, all the procedures run smoothly (even when I had not yet updated the open_cursors parameter).
    I was thinking of the following, but maybe you have some other ideas?
    Does this have anything to do with my procedures not being stored procedures?
    Or should i be committing records within my procedures instead of out of it?
    I really have run into a wall and would really appreciate any tips or helps on this. Thanks in advance!
    My basic pl/sql code looks like below. I did not give the actual details cause it will be too long (up to 5000 lines).
    DECLARE
    PROCEDURE proc1
    IS
        CURSOR cur_hca
           is
               select ...from..where;
       TYPE cur_hca_fetch
            Is TABLE OF cur_hca%ROWTYPE
                INDEX BY PLS_INTEGER;
        temp_collect cur_hca_fetch;
    BEGIN
       open cur_hca;         --cur_hca is the cursor name.
                                      --i use exactly the same cursor name in the other procedures
          loop
             fetch cur_hca bulk collect into temp_collect LIMIT 1000;
             exit when temp_collect.count=0
             for indx in 1 .. temp_collect.count
                loop
                  ...run some sql
                end loop;
          end loop;
      close cur_hca;
    END proc1;
    PROCEDURE proc2   --almost the same as above the only changes are the query for the
                                 -- cursor and the sql that happens for each record
    IS
    BEGIN
       open cur_hca;         --cur_hca is my cursor name
          loop
          end loop;
      close cur_hca;
    END proc2;
    ... up to 40 other very similar procedures
    BEGIN
       proc1;
       commit;
       select a.value into strtxt
            from v$mystat a, v$statname b
            where a.statistic# = b.statistic#
            and a.statistic#= 3;
      DBMS_OUTPUT.PUT_LINE('Number of Cursors After STATUSproc1: ' || strtxt); 
       proc2;
       commit;
       select a.value into strtxt
            from v$mystat a, v$statname b
            where a.statistic# = b.statistic#
            and a.statistic#= 3;
       DBMS_OUTPUT.PUT_LINE('Number of Cursors After STATUSproc2: ' || strtxt); 
       ... 40 other procedures
    END;Edited by: user4872285 on May 6, 2013 6:49 PM
    Edited by: user4872285 on May 6, 2013 7:01 PM
    Edited by: user4872285 on May 6, 2013 8:02 PM
    Edited by: user4872285 on May 6, 2013 8:03 PM

    PL/SQL code usually leaks reference cursors and DBMS_SQL cursors - as the ref cursor/DBMS_SQL interface used has a global (session static) scope.
    PL/SQL has an intelligent garbage collector that will close local implicit and explicit cursors, when the cursor variable goes out of scope.
    If you define an explicit cursor globally (package interface), then it can only be opened once. The 2nd attempt results in a ORA-06511: PL/SQL: cursor already open exception. So code cannot leak explicit cursors as code cannot reopen an existing opened explicit cursor.
    I have never seen Oracle leaking cursors internally. So I would be hesitant to call what you are seeing, a bug. If your code is using explicit cursors (even static/global ones), your code cannot leak these cursors, even if your code does not close them. Worse case - the cursor remains open, however new copies cannot be created while it is open.
    So I think your are looking at the wrong thing - explicit cursors. These are not the cursors that are leaking in my view (simply because code cannot reuse and open an already opened explicit cursor). Here is an example:
    SQL> show parameter cursors
    NAME                                 TYPE        VALUE
    open_cursors                         integer     300
    session_cached_cursors               integer     50
    // procedure that seems to "leak" an explicit cursor handle
    // as it does not explicitly closes the handle
    SQL> create or replace procedure CursorUse is
      2          cursor c is select e.* from emp e;
      3          empRow  emp%RowType;
      4  begin
      5          open c;
      6          fetch c into empRow;
      7          --// not closing explicit cursor handle
      8          --// and going out-of-scope
      9  end;
    10  /
    Procedure created.
    // current session stats
    SQL> select b.name, a.value from v$mystat a, v$statname b where a.statistic# = b.statistic# and b.name like '%open%cursor%';
    NAME                                  VALUE
    opened cursors cumulative                91
    opened cursors current                    2
    // execute proc that "leaks" a cursor, 10000 times
    SQL> begin
      2          for i in 1..10000 loop
      3                  CursorUse;
      4          end loop;
      5  end;
      6  /
    PL/SQL procedure successfully completed.
    // no errors due to cursor leakage
    // session stats: no cursor leakage occurred as
    // PL/SQL's garbage collector cleaned (and closed)
    // cursor handles when these became out-of-scope
    SQL> select b.name, a.value from v$mystat a, v$statname b where a.statistic# = b.statistic# and b.name like '%open%cursor%';
    NAME                                  VALUE
    opened cursors cumulative            10,095
    opened cursors current                    2
    SQL> So the cursor leakage you are seeing is caused by something else... so what else is part of the code, or the session, that you have not yet mentioned?

  • When should be package invalidated?

    Hello guys,
    I would need again some help...
    My question is: When exactly should be package invalidated?
    Consider following situation:
    We have two packages, one contains constants (in its specification), the other is reading these constants. Package is reading these constants in package body and package spec as well. Now, when I add a new constant to the first package and recompile it, should this invalidate the other package??? The new added constant is not used in the other package.
    In reality, we have a Constant package, containing all constants in its specification. One package (test_pkg) is reading some constant let say form line 100. Now we add new constant let say to line 50. When we recompile the constant package, planty of packages get invalidated because they are reading from it. We recompile all invalid packages. However test_pkg is not invalidated!!! Now if we run the code from test_pkg, it is still reading the constant from line 100, so it is reading it from wrong place and the constant has wrong value! The only thing what help is to recompile the test_pkg.
    So it looks like the reference to Constant package wasn't updated.
    Why isn't test_pkg invalidated???
    Oracle version:
    SELECT * FROM V$VERSION;
    Oracle Database 11g Release 11.2.0.1.0 - 64bit Production
    PL/SQL Release 11.2.0.1.0 - Production
    "CORE     11.2.0.1.0     Production"
    TNS for Linux: Version 11.2.0.1.0 - Production
    NLSRTL Version 11.2.0.1.0 - Production

    From my standard library of responses...
    Packages tend to fail because of their "package state". A package has a "state" when it contains package level variables/constants etc. and the package is called. Upon first calling the package, the "state" is created in memory to hold the values of those variables etc. If an object that the package depends upon e.g. a table is altered in some way e.g. dropped and recreated, then because of the database dependencies, the package takes on an INVALID status. When you next make a call to the package, Oracle looks at the status and sees that it is invalid, then determines that the package has a "state". Because something has altered that the package depended upon, the state is taken as being out of date and is discarded, thus causing the "Package state has been discarded" error message.
    If a package does not have package level variables etc. i.e. the "state" then, taking the same example above, the package takes on an INVALID status, but when you next make a call to the package, Oracle sees it as Invalid, but knows that there is no "state" attached to it, and so is able to recompile the package automatically and then carry on execution without causing any error messages. The only exception here is if the thing that the package was dependant on has changes in such a way that the package cannot compile, in which case you'll get an Invalid package type of error.
    And if you want to know how to prevent discarded package states....
    Move all constants and variables into a stand-alone package spec and reference those from your initial package. Thus when the status of your original package is invlidated for whatever reason, it has no package state and can be recompiled automatically, however the package containing the vars/const will not become invalidated as it has no dependencies, so the state that is in memory for that package will remain and can continue to be used.
    As for having package level cursors, you'll need to make these local to the procedures/functions using them as you won't be able to reference cursors across packages like that (not sure about using REF CURSORS though.... there's one for me to investigate!)
    This first example shows the package state being invalided by the addition of a new column on the table, and causing it to give a "Package state discarded" error...
    SQL> set serveroutput on
    SQL>
    SQL> create table dependonme (x number)
      2  /
    Table created.
    SQL>
    SQL> insert into dependonme values (5)
      2  /
    1 row created.
    SQL>
    SQL> create or replace package mypkg is
      2    procedure myproc;
      3  end mypkg;
      4  /
    Package created.
    SQL>
    SQL> create or replace package body mypkg is
      2    v_statevar number := 5; -- this means my package has a state
      3
      4    procedure myproc is
      5      myval number;
      6    begin
      7      select x
      8      into myval
      9      from dependonme;
    10
    11      myval := myval * v_statevar;
    12      DBMS_OUTPUT.PUT_LINE('My Result is: '||myval);
    13    end;
    14  end mypkg;
    15  /
    Package body created.
    SQL>
    SQL> exec mypkg.myproc
    My Result is: 25
    PL/SQL procedure successfully completed.
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        VALID
    SQL>
    SQL>
    SQL> alter table dependonme add (y number)
      2  /
    Table altered.
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        INVALID
    SQL>
    SQL> exec mypkg.myproc
    BEGIN mypkg.myproc; END;
    ERROR at line 1:
    ORA-04068: existing state of packages has been discarded
    ORA-04061: existing state of package body "SCOTT.MYPKG" has been invalidated
    ORA-06508: PL/SQL: could not find program unit being called: "SCOTT.MYPKG"
    ORA-06512: at line 1
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        INVALID
    SQL>
    SQL> exec mypkg.myproc
    PL/SQL procedure successfully completed.
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        VALIDAnd this next example shows how having the package variables in their own package spec, allows the package to automatically recompile when it is called even though it became invalidated by the action of adding a column to the table.
    SQL> drop table dependonme
      2  /
    Table dropped.
    SQL>
    SQL> drop package mypkg
      2  /
    Package dropped.
    SQL>
    SQL> set serveroutput on
    SQL>
    SQL> create table dependonme (x number)
      2  /
    Table created.
    SQL>
    SQL> insert into dependonme values (5)
      2  /
    1 row created.
    SQL>
    SQL> create or replace package mypkg is
      2    procedure myproc;
      3  end mypkg;
      4  /
    Package created.
    SQL>
    SQL> create or replace package mypkg_state is
      2    v_statevar number := 5; -- package state in seperate package spec
      3  end mypkg_state;
      4  /
    Package created.
    SQL>
    SQL> create or replace package body mypkg is
      2    -- this package has no state area
      3
      4    procedure myproc is
      5      myval number;
      6    begin
      7      select x
      8      into myval
      9      from dependonme;
    10
    11      myval := myval * mypkg_state.v_statevar;  -- note: references the mypkg_state package
    12      DBMS_OUTPUT.PUT_LINE('My Result is: '||myval);
    13    end;
    14  end mypkg;
    15  /
    Package body created.
    SQL>
    SQL> exec mypkg.myproc
    My Result is: 25
    PL/SQL procedure successfully completed.
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        VALID
    SQL>
    SQL> alter table dependonme add (y number)
      2  /
    Table altered.
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        INVALID
    SQL>
    SQL> exec mypkg.myproc
    My Result is: 25
    PL/SQL procedure successfully completed.

  • Package procedure in invalid state

    Hi all,
    We are having an application in C# and backend oracle 10g placed in Location1.
    There is modification in Packaged procedure. So we remotely (from Location2) connected to Location1 and that Packaged procedure is created.
    This Packaged procedure has been created (in Location1 ) without any errors. But this procedure is in INVALID state. We tried to compile it remotely by using following statements, but still this is in invalid state .
    ALTER PACKAGE my_package COMPILE;
    ALTER PACKAGE my_package COMPILE BODY;
    If we run this package and package body manually, without any modifications after creating it remotly, it is becoming VALID state.
    I am not getting any idea, why it is creating in INVALID state. Any help is appreciated.
    Thanks in advance,
    Pal

    Ok, here's a previous response that I gave re. packages and their "states". Should give you a good idea what a state is...
    Packages tend to fail because of their "package state". A package has a "state" when it contains package level variables/constants etc. and the package is called. Upon first calling the package, the "state" is created in memory to hold the values of those variables etc. If an object that the package depends upon e.g. a table is altered in some way e.g. dropped and recreated, then because of the database dependencies, the package takes on an INVALID status. When you next make a call to the package, Oracle looks at the status and sees that it is invalid, then determines that the package has a "state". Because something has altered that the package depended upon, the state is taken as being out of date and is discarded, thus causing the "Package state has been discarded" error message.
    If a package does not have package level variables etc. i.e. the "state" then, taking the same example above, the package takes on an INVALID status, but when you next make a call to the package, Oracle sees it as Invalid, but knows that there is no "state" attached to it, and so is able to recompile the package automatically and then carry on execution without causing any error messages. The only exception here is if the thing that the package was dependant on has changes in such a way that the package cannot compile, in which case you'll get an Invalid package type of error.
    And if you want to know how to prevent discarded package states....
    Move all constants and variables into a stand-alone package spec and reference those from your initial package. Thus when the status of your original package is invlidated for whatever reason, it has no package state and can be recompiled automatically, however the package containing the vars/const will not become invalidated as it has no dependencies, so the state that is in memory for that package will remain and can continue to be used.
    As for having package level cursors, you'll need to make these local to the procedures/functions using them as you won't be able to reference cursors across packages like that (not sure about using REF CURSORS though.... there's one for me to investigate!)
    This first example shows the package state being invalided by the addition of a new column on the table, and causing it to give a "Package state discarded" error...
    SQL> set serveroutput on
    SQL>
    SQL> create table dependonme (x number)
      2  /
    Table created.
    SQL>
    SQL> insert into dependonme values (5)
      2  /
    1 row created.
    SQL>
    SQL> create or replace package mypkg is
      2    procedure myproc;
      3  end mypkg;
      4  /
    Package created.
    SQL>
    SQL> create or replace package body mypkg is
      2    v_statevar number := 5; -- this means my package has a state
      3
      4    procedure myproc is
      5      myval number;
      6    begin
      7      select x
      8      into myval
      9      from dependonme;
    10
    11      myval := myval * v_statevar;
    12      DBMS_OUTPUT.PUT_LINE('My Result is: '||myval);
    13    end;
    14  end mypkg;
    15  /
    Package body created.
    SQL>
    SQL> exec mypkg.myproc
    My Result is: 25
    PL/SQL procedure successfully completed.
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        VALID
    SQL>
    SQL>
    SQL> alter table dependonme add (y number)
      2  /
    Table altered.
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        INVALID
    SQL>
    SQL> exec mypkg.myproc
    BEGIN mypkg.myproc; END;
    ERROR at line 1:
    ORA-04068: existing state of packages has been discarded
    ORA-04061: existing state of package body "CRISP_INTELL.MYPKG" has been invalidated
    ORA-06508: PL/SQL: could not find program unit being called: "CRISP_INTELL.MYPKG"
    ORA-06512: at line 1
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        INVALID
    SQL>
    SQL> exec mypkg.myproc
    PL/SQL procedure successfully completed.
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        VALIDAnd this next example shows how having the package variables in their own package spec, allows the package to automatically recompile when it is called even though it became invalidated by the action of adding a column to the table.
    SQL> drop table dependonme
      2  /
    Table dropped.
    SQL>
    SQL> drop package mypkg
      2  /
    Package dropped.
    SQL>
    SQL> set serveroutput on
    SQL>
    SQL> create table dependonme (x number)
      2  /
    Table created.
    SQL>
    SQL> insert into dependonme values (5)
      2  /
    1 row created.
    SQL>
    SQL> create or replace package mypkg is
      2    procedure myproc;
      3  end mypkg;
      4  /
    Package created.
    SQL>
    SQL> create or replace package mypkg_state is
      2    v_statevar number := 5; -- package state in seperate package spec
      3  end mypkg_state;
      4  /
    Package created.
    SQL>
    SQL> create or replace package body mypkg is
      2    -- this package has no state area
      3
      4    procedure myproc is
      5      myval number;
      6    begin
      7      select x
      8      into myval
      9      from dependonme;
    10
    11      myval := myval * mypkg_state.v_statevar;  -- note: references the mypkg_state package
    12      DBMS_OUTPUT.PUT_LINE('My Result is: '||myval);
    13    end;
    14  end mypkg;
    15  /
    Package body created.
    SQL>
    SQL> exec mypkg.myproc
    My Result is: 25
    PL/SQL procedure successfully completed.
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        VALID
    SQL>
    SQL> alter table dependonme add (y number)
      2  /
    Table altered.
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        INVALID
    SQL>
    SQL> exec mypkg.myproc
    My Result is: 25
    PL/SQL procedure successfully completed.

  • Valid packages goes invalid when executing application

    Friends of pl/sql
    When we execute our application we find that 2 of our main packiages go invalid for no reason. The packages compiles just fine when we then compile them. So, no syntax errors. But it stops our application with a lovely "existing state of packages have been discarded......." type error. Not too nice.
    What are some of the things to check on for why the package goes invalid ?
    We are using TOAD and sql*monitor to trace the process at the moment...........
    Any solutions out there ?
    Environment : Oracle Enterprise Linux 5 on Oracle 11.1.0.6 (latest patch available). Oracle 11 client as well.
    Edited by: ow001294 on Apr 15, 2009 9:24 AM

    One of my older standard responses (haven't use this in a while)..
    Packages tend to fail because of their "package state". A package has a "state" when it contains package level variables/constants etc. and the package is called. Upon first calling the package, the "state" is created in memory to hold the values of those variables etc. If an object that the package depends upon e.g. a table is altered in some way e.g. dropped and recreated, then because of the database dependencies, the package takes on an INVALID status. When you next make a call to the package, Oracle looks at the status and sees that it is invalid, then determines that the package has a "state". Because something has altered that the package depended upon, the state is taken as being out of date and is discarded, thus causing the "Package state has been discarded" error message.
    If a package does not have package level variables etc. i.e. the "state" then, taking the same example above, the package takes on an INVALID status, but when you next make a call to the package, Oracle sees it as Invalid, but knows that there is no "state" attached to it, and so is able to recompile the package automatically and then carry on execution without causing any error messages. The only exception here is if the thing that the package was dependant on has changes in such a way that the package cannot compile, in which case you'll get an Invalid package type of error.
    And if you want to know how to prevent discarded package states....
    Move all constants and variables into a stand-alone package spec and reference those from your initial package. Thus when the status of your original package is invlidated for whatever reason, it has no package state and can be recompiled automatically, however the package containing the vars/const will not become invalidated as it has no dependencies, so the state that is in memory for that package will remain and can continue to be used.
    As for having package level cursors, you'll need to make these local to the procedures/functions using them as you won't be able to reference cursors across packages like that (not sure about using REF CURSORS though.... there's one for me to investigate!)
    This first example shows the package state being invalided by the addition of a new column on the table, and causing it to give a "Package state discarded" error...
    SQL> set serveroutput on
    SQL>
    SQL> create table dependonme (x number)
      2  /
    Table created.
    SQL>
    SQL> insert into dependonme values (5)
      2  /
    1 row created.
    SQL>
    SQL> create or replace package mypkg is
      2    procedure myproc;
      3  end mypkg;
      4  /
    Package created.
    SQL>
    SQL> create or replace package body mypkg is
      2    v_statevar number := 5; -- this means my package has a state
      3
      4    procedure myproc is
      5      myval number;
      6    begin
      7      select x
      8      into myval
      9      from dependonme;
    10
    11      myval := myval * v_statevar;
    12      DBMS_OUTPUT.PUT_LINE('My Result is: '||myval);
    13    end;
    14  end mypkg;
    15  /
    Package body created.
    SQL>
    SQL> exec mypkg.myproc
    My Result is: 25
    PL/SQL procedure successfully completed.
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        VALID
    SQL>
    SQL>
    SQL> alter table dependonme add (y number)
      2  /
    Table altered.
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        INVALID
    SQL>
    SQL> exec mypkg.myproc
    BEGIN mypkg.myproc; END;
    ERROR at line 1:
    ORA-04068: existing state of packages has been discarded
    ORA-04061: existing state of package body "SCOTT.MYPKG" has been invalidated
    ORA-06508: PL/SQL: could not find program unit being called: "SCOTT.MYPKG"
    ORA-06512: at line 1
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        INVALID
    SQL>
    SQL> exec mypkg.myproc
    PL/SQL procedure successfully completed.
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        VALIDAnd this next example shows how having the package variables in their own package spec, allows the package to automatically recompile when it is called even though it became invalidated by the action of adding a column to the table.
    SQL> drop table dependonme
      2  /
    Table dropped.
    SQL>
    SQL> drop package mypkg
      2  /
    Package dropped.
    SQL>
    SQL> set serveroutput on
    SQL>
    SQL> create table dependonme (x number)
      2  /
    Table created.
    SQL>
    SQL> insert into dependonme values (5)
      2  /
    1 row created.
    SQL>
    SQL> create or replace package mypkg is
      2    procedure myproc;
      3  end mypkg;
      4  /
    Package created.
    SQL>
    SQL> create or replace package mypkg_state is
      2    v_statevar number := 5; -- package state in seperate package spec
      3  end mypkg_state;
      4  /
    Package created.
    SQL>
    SQL> create or replace package body mypkg is
      2    -- this package has no state area
      3
      4    procedure myproc is
      5      myval number;
      6    begin
      7      select x
      8      into myval
      9      from dependonme;
    10
    11      myval := myval * mypkg_state.v_statevar;  -- note: references the mypkg_state package
    12      DBMS_OUTPUT.PUT_LINE('My Result is: '||myval);
    13    end;
    14  end mypkg;
    15  /
    Package body created.
    SQL>
    SQL> exec mypkg.myproc
    My Result is: 25
    PL/SQL procedure successfully completed.
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        VALID
    SQL>
    SQL> alter table dependonme add (y number)
      2  /
    Table altered.
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        INVALID
    SQL>
    SQL> exec mypkg.myproc
    My Result is: 25
    PL/SQL procedure successfully completed.

  • Cursor difference (REF Cursor & Sys_Refcursor)

    Hi,
    Is there any difference between REF Cursor and SYS_Refcursor?
    I see some packages using sys_refcursor and some using REF Cursor.
    Package 1 (Spec):
       PROCEDURE s_demo1 (
          ret_rset   OUT      sys_refcursor
    Package 2 (Spec):
    TYPE cur_set IS REF CURSOR;
    PROCEDURE s_test1 (out_data OUT cur_set);
    PROCEDURE s_test2 (out_data OUT cur_set);I am going through this link (http://sql-plsql.blogspot.com/2007/05/oracle-plsql-ref-cursors.html) but didn't find the answer.

    DomBrooks wrote:
    John - don't get me wrong, I'm not suggesting that as soon as something like SYS_REFCURSOR comes along, everything should get rewritten. It's just I still see new packages written on 11g by, say mainly C# or java developers, which use this old style.
    But.... are you saying that you can't do this?
    CREATE OR REPLACE PACKAGE old_package AS
    TYPE pkg_cur IS REF CURSOR;
    FUNCTION foo(p_id IN NUMBER) RETURN sys_refcursor;
    END;
    CREATE OR REPLACE PACKAGE BODY old_package AS
    FUNCTION foo(p_id IN NUMBER) RETURN sys_refcursor IS
    l_cur sys_refcursor;
    BEGIN
    OPEN l_CUR FOR SELECT * FROM dual WHERE 1 = p_id;
    RETURN l_cur;
    END;
    END;
    Absolutely, I can even declare pkg_cursor as a sys_refcursor and all of the old calls will still work since sys_refcursor is just a ref cursor in disguise. What I cannot do is drop the declaration in the package spec since the outside callers rely on it, so since sys_refcusor is just a ref cursor in disguise, why use it?
    In fact, in OHOME/rdbms/admin/stdspec.sql which is the declarations for the package standard sys_refcursor is declared as:
      /* Adding a generic weak ref cursor type */
      type sys_refcursor is ref cursor;Since things declared in standard package (like data types, operators, all of the named exceptions etc.) are "globally" available without using the package name, sys_refcursor just provides a method to save a few keystrokes everywhere. It is no different functionally than a package declared ref cursor. The main difference is that you cannot create a strongly typed sys_refcursor, if you want/need one, you need to use a ref cursor.
    I do tend to use sys_refcursor in new code, but it took me a while to switch because there is not much real benefit as far as I can see.
    John
    Edited by: John Spencer on Nov 17, 2010 4:11 PM

  • DBMS_JOB using Packaged Functions but Package goes invalid

    Is there any way to check a package while running a PL/SQL procedure to see if it's state is valid and then catch the exception?
    In my case usually just calling any function in the package 1x clears it up but the procedure in question runs as a DBMS_JOB it just keeps failing. This procedure could run often enough that Oracle will mark it as broken but I want to give it every shot at execution on time instead of having to make it wait till the next cycle.
    What I would like to do is to catch the exception for the package state being invalid and basically have it go back to the beginning of the procedure and give it another try before failing in case it is just a failure because the package has been altered.
    Is there any way to do this?

    Firstly, I'll copy/paste my standard response regarding package state going invalid as it usually helps to have an understanding of these things...
    Packages tend to fail because of their "package state". A package has a "state" when it contains package level variables/constants etc. and the package is called. Upon first calling the package, the "state" is created in memory to hold the values of those variables etc. If an object that the package depends upon e.g. a table is altered in some way e.g. dropped and recreated, then because of the database dependencies, the package takes on an INVALID status. When you next make a call to the package, Oracle looks at the status and sees that it is invalid, then determines that the package has a "state". Because something has altered that the package depended upon, the state is taken as being out of date and is discarded, thus causing the "Package state has been discarded" error message.
    If a package does not have package level variables etc. i.e. the "state" then, taking the same example above, the package takes on an INVALID status, but when you next make a call to the package, Oracle sees it as Invalid, but knows that there is no "state" attached to it, and so is able to recompile the package automatically and then carry on execution without causing any error messages. The only exception here is if the thing that the package was dependant on has changes in such a way that the package cannot compile, in which case you'll get an Invalid package type of error.
    And if you want to know how to prevent discarded package states....
    Move all constants and variables into a stand-alone package spec and reference those from your initial package. Thus when the status of your original package is invlidated for whatever reason, it has no package state and can be recompiled automatically, however the package containing the vars/const will not become invalidated as it has no dependencies, so the state that is in memory for that package will remain and can continue to be used.
    As for having package level cursors, you'll need to make these local to the procedures/functions using them as you won't be able to reference cursors across packages like that (not sure about using REF CURSORS though.... there's one for me to investigate!)
    This first example shows the package state being invalided by the addition of a new column on the table, and causing it to give a "Package state discarded" error...
    SQL> set serveroutput on
    SQL>
    SQL> create table dependonme (x number)
      2  /
    Table created.
    SQL>
    SQL> insert into dependonme values (5)
      2  /
    1 row created.
    SQL>
    SQL> create or replace package mypkg is
      2    procedure myproc;
      3  end mypkg;
      4  /
    Package created.
    SQL>
    SQL> create or replace package body mypkg is
      2    v_statevar number := 5; -- this means my package has a state
      3
      4    procedure myproc is
      5      myval number;
      6    begin
      7      select x
      8      into myval
      9      from dependonme;
    10
    11      myval := myval * v_statevar;
    12      DBMS_OUTPUT.PUT_LINE('My Result is: '||myval);
    13    end;
    14  end mypkg;
    15  /
    Package body created.
    SQL>
    SQL> exec mypkg.myproc
    My Result is: 25
    PL/SQL procedure successfully completed.
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        VALID
    SQL>
    SQL>
    SQL> alter table dependonme add (y number)
      2  /
    Table altered.
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        INVALID
    SQL>
    SQL> exec mypkg.myproc
    BEGIN mypkg.myproc; END;
    ERROR at line 1:
    ORA-04068: existing state of packages has been discarded
    ORA-04061: existing state of package body "SCOTT.MYPKG" has been invalidated
    ORA-06508: PL/SQL: could not find program unit being called: "SCOTT.MYPKG"
    ORA-06512: at line 1
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        INVALID
    SQL>
    SQL> exec mypkg.myproc
    PL/SQL procedure successfully completed.
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        VALIDAnd this next example shows how having the package variables in their own package spec, allows the package to automatically recompile when it is called even though it became invalidated by the action of adding a column to the table.
    SQL> drop table dependonme
      2  /
    Table dropped.
    SQL>
    SQL> drop package mypkg
      2  /
    Package dropped.
    SQL>
    SQL> set serveroutput on
    SQL>
    SQL> create table dependonme (x number)
      2  /
    Table created.
    SQL>
    SQL> insert into dependonme values (5)
      2  /
    1 row created.
    SQL>
    SQL> create or replace package mypkg is
      2    procedure myproc;
      3  end mypkg;
      4  /
    Package created.
    SQL>
    SQL> create or replace package mypkg_state is
      2    v_statevar number := 5; -- package state in seperate package spec
      3  end mypkg_state;
      4  /
    Package created.
    SQL>
    SQL> create or replace package body mypkg is
      2    -- this package has no state area
      3
      4    procedure myproc is
      5      myval number;
      6    begin
      7      select x
      8      into myval
      9      from dependonme;
    10
    11      myval := myval * mypkg_state.v_statevar;  -- note: references the mypkg_state package
    12      DBMS_OUTPUT.PUT_LINE('My Result is: '||myval);
    13    end;
    14  end mypkg;
    15  /
    Package body created.
    SQL>
    SQL> exec mypkg.myproc
    My Result is: 25
    PL/SQL procedure successfully completed.
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        VALID
    SQL>
    SQL> alter table dependonme add (y number)
      2  /
    Table altered.
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        INVALID
    SQL>
    SQL> exec mypkg.myproc
    My Result is: 25
    PL/SQL procedure successfully completed.---------------------------------------------------------------------------------------------
    Secondly, from this above standard response, you can see how to check for package state if you want to determine it programatically.
    ;)

  • ORA-4068 Existing stage of package discarded - Techniques of avoid variable

    Hi all,
    I need to ‘strip’ the state from a package (let’s say PKG_MAIN). I’ve already transform all constants into functions but I have difficulties in finding the best solution for the variables. Most of the variables are collections and I cannot use temporary tables to replace them (performance issues). As well I have tried creating a package (PKG_VARIABLES) for all variables but, as you probably know, this is not a ‘fix’ because changing the PKG_VARIABLES will trigger, when calling the PKG_MAIN, the ORA-4068 anyway.
    Any ideas??
    Cheers,
    Harada

    [standard response for package state]
    Packages tend to fail because of their "package state". A package has a "state" when it contains package level variables/constants etc. and the package is called. Upon first calling the package, the "state" is created in memory to hold the values of those variables etc. If an object that the package depends upon e.g. a table is altered in some way e.g. dropped and recreated, then because of the database dependencies, the package takes on an INVALID status. When you next make a call to the package, Oracle looks at the status and sees that it is invalid, then determines that the package has a "state". Because something has altered that the package depended upon, the state is taken as being out of date and is discarded, thus causing the "Package state has been discarded" error message.
    If a package does not have package level variables etc. i.e. the "state" then, taking the same example above, the package takes on an INVALID status, but when you next make a call to the package, Oracle sees it as Invalid, but knows that there is no "state" attached to it, and so is able to recompile the package automatically and then carry on execution without causing any error messages. The only exception here is if the thing that the package was dependant on has changes in such a way that the package cannot compile, in which case you'll get an Invalid package type of error.
    And if you want to know how to prevent discarded package states....
    Move all constants and variables into a stand-alone package spec and reference those from your initial package. Thus when the status of your original package is invlidated for whatever reason, it has no package state and can be recompiled automatically, however the package containing the vars/const will not become invalidated as it has no dependencies, so the state that is in memory for that package will remain and can continue to be used.
    As for having package level cursors, you'll need to make these local to the procedures/functions using them as you won't be able to reference cursors across packages like that (not sure about using REF CURSORS though.... there's one for me to investigate!)
    This first example shows the package state being invalided by the addition of a new column on the table, and causing it to give a "Package state discarded" error...
    SQL> set serveroutput on
    SQL>
    SQL> create table dependonme (x number)
      2  /
    Table created.
    SQL>
    SQL> insert into dependonme values (5)
      2  /
    1 row created.
    SQL>
    SQL> create or replace package mypkg is
      2    procedure myproc;
      3  end mypkg;
      4  /
    Package created.
    SQL>
    SQL> create or replace package body mypkg is
      2    v_statevar number := 5; -- this means my package has a state
      3
      4    procedure myproc is
      5      myval number;
      6    begin
      7      select x
      8      into myval
      9      from dependonme;
    10
    11      myval := myval * v_statevar;
    12      DBMS_OUTPUT.PUT_LINE('My Result is: '||myval);
    13    end;
    14  end mypkg;
    15  /
    Package body created.
    SQL>
    SQL> exec mypkg.myproc
    My Result is: 25
    PL/SQL procedure successfully completed.
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        VALID
    SQL>
    SQL>
    SQL> alter table dependonme add (y number)
      2  /
    Table altered.
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        INVALID
    SQL>
    SQL> exec mypkg.myproc
    BEGIN mypkg.myproc; END;
    ERROR at line 1:
    ORA-04068: existing state of packages has been discarded
    ORA-04061: existing state of package body "SCOTT.MYPKG" has been invalidated
    ORA-06508: PL/SQL: could not find program unit being called: "SCOTT.MYPKG"
    ORA-06512: at line 1
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        INVALID
    SQL>
    SQL> exec mypkg.myproc
    PL/SQL procedure successfully completed.
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        VALIDAnd this next example shows how having the package variables in their own package spec, allows the package to automatically recompile when it is called even though it became invalidated by the action of adding a column to the table.
    SQL> drop table dependonme
      2  /
    Table dropped.
    SQL>
    SQL> drop package mypkg
      2  /
    Package dropped.
    SQL>
    SQL> set serveroutput on
    SQL>
    SQL> create table dependonme (x number)
      2  /
    Table created.
    SQL>
    SQL> insert into dependonme values (5)
      2  /
    1 row created.
    SQL>
    SQL> create or replace package mypkg is
      2    procedure myproc;
      3  end mypkg;
      4  /
    Package created.
    SQL>
    SQL> create or replace package mypkg_state is
      2    v_statevar number := 5; -- package state in seperate package spec
      3  end mypkg_state;
      4  /
    Package created.
    SQL>
    SQL> create or replace package body mypkg is
      2    -- this package has no state area
      3
      4    procedure myproc is
      5      myval number;
      6    begin
      7      select x
      8      into myval
      9      from dependonme;
    10
    11      myval := myval * mypkg_state.v_statevar;  -- note: references the mypkg_state package
    12      DBMS_OUTPUT.PUT_LINE('My Result is: '||myval);
    13    end;
    14  end mypkg;
    15  /
    Package body created.
    SQL>
    SQL> exec mypkg.myproc
    My Result is: 25
    PL/SQL procedure successfully completed.
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        VALID
    SQL>
    SQL> alter table dependonme add (y number)
      2  /
    Table altered.
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        INVALID
    SQL>
    SQL> exec mypkg.myproc
    My Result is: 25
    PL/SQL procedure successfully completed.

  • Package Spec

    1. what is the purpose of creating bodyless package ? what are the advantages of creating like this ?
    2. what is the reason for using "CREATE OR REPLACE PACKAGE" instead of dropping and creating ?

    Balarenganathan wrote:
    1. what is the purpose of creating bodyless package ? what are the advantages of creating like this ?Here's one example of a user for creating a bodyless package...
    Packages tend to fail because of their "package state". A package has a "state" when it contains package level variables/constants etc. and the package is called. Upon first calling the package, the "state" is created in memory to hold the values of those variables etc. If an object that the package depends upon e.g. a table is altered in some way e.g. dropped and recreated, then because of the database dependencies, the package takes on an INVALID status. When you next make a call to the package, Oracle looks at the status and sees that it is invalid, then determines that the package has a "state". Because something has altered that the package depended upon, the state is taken as being out of date and is discarded, thus causing the "Package state has been discarded" error message.
    If a package does not have package level variables etc. i.e. the "state" then, taking the same example above, the package takes on an INVALID status, but when you next make a call to the package, Oracle sees it as Invalid, but knows that there is no "state" attached to it, and so is able to recompile the package automatically and then carry on execution without causing any error messages. The only exception here is if the thing that the package was dependant on has changes in such a way that the package cannot compile, in which case you'll get an Invalid package type of error.
    And if you want to know how to prevent discarded package states....
    Move all constants and variables into a stand-alone package spec and reference those from your initial package. Thus when the status of your original package is invlidated for whatever reason, it has no package state and can be recompiled automatically, however the package containing the vars/const will not become invalidated as it has no dependencies, so the state that is in memory for that package will remain and can continue to be used.
    As for having package level cursors, you'll need to make these local to the procedures/functions using them as you won't be able to reference cursors across packages like that (not sure about using REF CURSORS though.... there's one for me to investigate!)
    This first example shows the package state being invalided by the addition of a new column on the table, and causing it to give a "Package state discarded" error...
    SQL> set serveroutput on
    SQL>
    SQL> create table dependonme (x number)
      2  /
    Table created.
    SQL>
    SQL> insert into dependonme values (5)
      2  /
    1 row created.
    SQL>
    SQL> create or replace package mypkg is
      2    procedure myproc;
      3  end mypkg;
      4  /
    Package created.
    SQL>
    SQL> create or replace package body mypkg is
      2    v_statevar number := 5; -- this means my package has a state
      3
      4    procedure myproc is
      5      myval number;
      6    begin
      7      select x
      8      into myval
      9      from dependonme;
    10
    11      myval := myval * v_statevar;
    12      DBMS_OUTPUT.PUT_LINE('My Result is: '||myval);
    13    end;
    14  end mypkg;
    15  /
    Package body created.
    SQL>
    SQL> exec mypkg.myproc
    My Result is: 25
    PL/SQL procedure successfully completed.
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        VALID
    SQL>
    SQL>
    SQL> alter table dependonme add (y number)
      2  /
    Table altered.
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        INVALID
    SQL>
    SQL> exec mypkg.myproc
    BEGIN mypkg.myproc; END;
    ERROR at line 1:
    ORA-04068: existing state of packages has been discarded
    ORA-04061: existing state of package body "SCOTT.MYPKG" has been invalidated
    ORA-06508: PL/SQL: could not find program unit being called: "SCOTT.MYPKG"
    ORA-06512: at line 1
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        INVALID
    SQL>
    SQL> exec mypkg.myproc
    PL/SQL procedure successfully completed.
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        VALIDAnd this next example shows how having the package variables in their own package spec, allows the package to automatically recompile when it is called even though it became invalidated by the action of adding a column to the table.
    SQL> drop table dependonme
      2  /
    Table dropped.
    SQL>
    SQL> drop package mypkg
      2  /
    Package dropped.
    SQL>
    SQL> set serveroutput on
    SQL>
    SQL> create table dependonme (x number)
      2  /
    Table created.
    SQL>
    SQL> insert into dependonme values (5)
      2  /
    1 row created.
    SQL>
    SQL> create or replace package mypkg is
      2    procedure myproc;
      3  end mypkg;
      4  /
    Package created.
    SQL>
    SQL> create or replace package mypkg_state is
      2    v_statevar number := 5; -- package state in seperate package spec
      3  end mypkg_state;
      4  /
    Package created.
    SQL>
    SQL> create or replace package body mypkg is
      2    -- this package has no state area
      3
      4    procedure myproc is
      5      myval number;
      6    begin
      7      select x
      8      into myval
      9      from dependonme;
    10
    11      myval := myval * mypkg_state.v_statevar;  -- note: references the mypkg_state package
    12      DBMS_OUTPUT.PUT_LINE('My Result is: '||myval);
    13    end;
    14  end mypkg;
    15  /
    Package body created.
    SQL>
    SQL> exec mypkg.myproc
    My Result is: 25
    PL/SQL procedure successfully completed.
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        VALID
    SQL>
    SQL> alter table dependonme add (y number)
      2  /
    Table altered.
    SQL>
    SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
      2  /
    OBJECT_NAME
    OBJECT_TYPE         STATUS
    MYPKG
    PACKAGE             VALID
    MYPKG
    PACKAGE BODY        INVALID
    SQL>
    SQL> exec mypkg.myproc
    My Result is: 25
    PL/SQL procedure successfully completed.The other uses are of course that you just want to create a load of type definitions etc. to be used by multiple packages elsewhere. ;)
    2. what is the reason for using "CREATE OR REPLACE PACKAGE" instead of dropping and creating ?What's the reason for dropping and recreating when you've got the option to create or replace? ;)

  • Report Background Engine Memory Increasing on Reports 6i

    Hi... we recently upgraded our ERP system from Developer 2000 to 6i. Some of our functions require many reports to print at once (labels, invoices, pick tickets, etc).. What we've noticed is that when we do this, the report background engine increases in memory significantly and does not release the memory when finished.... and can cripple the work station.
    We know we can issue the Oracle_shutdown parameter to close the RBE after each report, but are there any other options as we feel this may slow down our printing?
    Thanks,
    Scott

    If you use "dynamic" ref cursor, your package specification must have "dynamic" ref cursor type for (dynamic) query
    (from 9i we can use predefined SYS_REFCURSOR built-in data type) and "static" ref cursor type for Report Layout.
    SELECT statement in "dynamic" ref cursor must have the same number and type of columns as "static" ref cursor type.
    And, of course, your package must be stored (=database) package, because PL/SQL engine in Reports 6i is v.8.0
    but "dynamic" ref cursor is a new feature of PL/SQL v.8.1.
    See
    re:re:re:Can we create report based on stored procedure
    Regards,
    Zlatko

  • Code Search for Keywords

    Hi All,
    I need some help from advance sql users.
    I have for ex. some 100 table names in a custom table. and i want to search oracle's dba_source table for packages/functions/procedures. The output i want is e.g.
    <Package Name> < Table Name>
    Here this <Table name> is referred by the <Package Name>. In short i am trying to see these 100 table are referred by how many package/procedure/function code..i.e one by one.
    I am trying to find a way to write a SQL Query for this.(not cursors and packages etc.). Please help with your opinions
    Thanks

    You don't need to do all that job for your purpose.
    Try this
    select *
    from dba_dependenciesBye Alessandro

Maybe you are looking for

  • Sale order Processing status

    Hi gurus,            Where we check the sale order processing status configuration ? Regards, T.Murugu

  • How do you know if the wireless keyboard is turned on or off?

    When I press the power button on the wireless keyboard (A1314) the tiny light lights up and then goes out. When I press the power key again the tiny light lights up and then goes out. How can I tell which is which? When is the keyboard on and when is

  • URGENT: weblogic.management.admin in weblogic 9.2 API

    Hi, Does anyone know what replaced "weblogic.management.admin" in Weblogic 9.2?. It shows in list of deprecated APIs. But does nt specify the replacement. http://edocs.bea.com/wls/docs92/javadocs/deprecated-list.html

  • How to personalize field appearance based on stored procedure

    Hi. Apologies if this is the wrong forum. I have a customer (SR 6379076.994) wishing to include a restriction on a Self-Service Web Page (Page: Asset Management, Tab: Work Orders, Nav: Work Order Completion - Work Order Completion, Responsibility: Ma

  • Default employee cost center based on work center

    Greetings, How can I default an employee's home cost center in IT0001 based on their work center assignment? I've tried linking both the employee's position and their org unit to the work center via CR02. This did create the IT1001 records. The work