Reg. Converting a package level cursor into a Ref cursor

Hi Guru's,
I am in need of converting a package level cursor which contains "FOR UPDATE OF" clause into a Ref cursor where the query will be dynamically built in with the needed table name and other parameters.
Using that cursor many Update statement's were performed with "WHERE CURRENT OF" clause included in it.
Now I changed my cursor into Ref cursor, but when i compile the cursor that is built dynamical is not identified, since i am getting error.
Can any one tell me how to proceed in order to implement it?
Do I need only go for dynamic bulding of the whole procedure.
With Best Regards,
Vijayasekaran.N

May be you can work it around with ROWID. Like this
Say this is your actual code.
declare
     cursor c
     is
     select *
       from t
        for update of name;
     lno t.no%type;
     lname t.name%type;
begin
     open c;
     loop
          fetch c into lno, lname;
          exit when c%notfound;
          update t set name = lno||lname
           where current of c;
     end loop;
     close c;
end;
/With refcursor you can do this.
declare
     type rc is ref cursor;
     c rc;
     lno t.no%type;
     lname t.name%type;
     lrowid rowid;
begin
     open c for 'select rowid rid, t.*
               from t
                for update of name';
     loop
          fetch c into lrowid,lno, lname;
          exit when c%notfound;
          update t set name = lno||lname
           where rowid = lrowid;
     end loop;
     close c;
end;
/Edited by: Karthick_Arp on Dec 26, 2008 2:00 AM

Similar Messages

  • How to put a collection into a Ref Cursor?

    Hi,
    I am trying to create a procedure (inside a package) which fills a collection and I need to fill a ref cursor (out parameter) with this collection. I can fill the collection but I how can I fill the ref cursor? I am receiving the message "PL/SQL: ORA-00902: invalid datatype" (Highlighted below as comments)
    I have a limitation: I am not allowed to create any kind of objects at the database schema level, so I have to create them inside the package. I'm writting it with SQL Tools 1.4, I'm also not allowed to do this in SQL+.
    This is the code of the package. The cursors' selects were simplified just because they are not the problem, but their structure is like follows below.
    CREATE OR REPLACE PACKAGE U3.PKG_TESTE AS
    TYPE REC_TYPE IS RECORD(
    COL1 VARCHAR2(50) ,
    COL2 VARCHAR2(100) ,
    COL3 VARCHAR2(20) ,
    COL4 VARCHAR2(30) ,
    COL5 VARCHAR2(100) ,
    COL6 VARCHAR2(50) ,
    COL7 NUMBER(3) ,
    COL8 VARCHAR2(30) ,
    COL9 VARCHAR2(16) ,
    COL10 VARCHAR2(50) ,
    COL11 NUMBER(4) ,
    COL12 VARCHAR2(40)
    TYPE REC_TYPE_LIST IS TABLE OF REC_TYPE
    INDEX BY BINARY_INTEGER;
    TYPE C_RESULTSET IS REF CURSOR;
    VAR_TAB_TESTE     REC_TYPE_LIST;
    PROCEDURE     Z_REC_INSTANCE
    pUSER_SYS_CODE VARCHAR2,
    pSYS_SEG_CODE VARCHAR2,
    pComplFiltro VARCHAR2,
    pCodInter NUMBER,
    cResultset out C_RESULTSET
    END PKG_TESTE ;
    CREATE OR REPLACE PACKAGE BODY U3.PKG_TESTE
    AS
    PROCEDURE Z_REC_INSTANCE
    pUSER_SYS_CODE varchar2,
    pSYS_SEG_CODE varchar2,
    pComplFiltro varchar2,
    pCodInter number
    AS
    cursor cur1 is
    select 'A' COL1, 'B' COL2, 'C' COL3, 'D' COL4, 'E' COL5,
    'F' COL6, 'G' COL7, 'H' COL8
    FROM DUAL;
    regCur1 cur1%rowtype;
    cursor cur2 is
    SELECT 'I' C1, 'J' C2, 'K' C3, 'L' C4
    FROM DUAL;
    regCur2 cur2%rowtype;
    varSQL varchar2(4000);
    varCOL10s varchar2(100);
    varFiltroAtrib varchar2(100);
    varCount number(10);
    BEGIN
    varCount := 1;
    open cur1;
    Loop
    fetch cur1 into regCur1;
    exit when cur1%notfound;
    open cur2;
    Loop
    fetch cur2 into regCur2;
    exit when cur2%notfound;
    VAR_TAB_TESTE(varCount).COL1 := regCur1.COL1;
    VAR_TAB_TESTE(varCount).COL2 := regCur1.COL2;
    VAR_TAB_TESTE(varCount).COL3 := regCur1.COL3;
    VAR_TAB_TESTE(varCount).COL4 := regCur1.COL4;
    VAR_TAB_TESTE(varCount).COL5 := regCur1.COL5;
    VAR_TAB_TESTE(varCount).COL6 := regCur1.COL6;
    VAR_TAB_TESTE(varCount).COL7 := regCur1.COL7;
    VAR_TAB_TESTE(varCount).COL8 := regCur1.COL8;
    VAR_TAB_TESTE(varCount).COL9 := regCur2.C1;
    VAR_TAB_TESTE(varCount).COL10 := regCur2.C2;
    VAR_TAB_TESTE(varCount).COL11 := regCur2.C3;
    VAR_TAB_TESTE(varCount).COL12 := regCur2.C4;
    varCount := varCount + 1;
    end Loop;
    end Loop;
    -- I'd like to do something like this:
    -- c_resultset := select * from var_tab_teste;
    -- but i don't know how to put the records of the type on the ref cursor,
    -- probably because I don't know how to select them
    -- pl/sql: ora-00902: invalid datatype
    for varCount in (select COL1 from table( CAST ( VAR_TAB_TESTE AS REC_TYPE_LIST ) ))
    loop
    dbms_output.put('WORKS');
    end loop;
    END Z_REC_INSTANCE;
    END PKG_TESTE;
    SHOW     ERR     PACKAGE          PKG_TESTE;
    SHOW     ERR     PACKAGE BODY     PKG_TESTE;
    SHOW     ERR     PROCEDURE     PKG_TESTE.Z_REC_INSTANCE;
    I'm using:
    Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production
    With the Partitioning, OLAP and Oracle Data Mining options
    JServer Release 9.2.0.1.0 - Production
    Thanks in advance.

    I don't have the exact version but in 9iOK I lied, I found a 9i instance ;-)
    Oracle9i Enterprise Edition Release 9.2.0.7.0 - 64bit Production
    JServer Release 9.2.0.7.0 - Production
    SQL> CREATE TABLE table_name (column_name VARCHAR2 (30));
    Table created.
    SQL> INSERT INTO table_name VALUES ('value one');
    1 row created.
    SQL> INSERT INTO table_name VALUES ('value two');
    1 row created.
    SQL> COMMIT;
    Commit complete.
    SQL> CREATE OR REPLACE PACKAGE package_name
      2  AS
      3     TYPE collection_type_name IS TABLE OF table_name%ROWTYPE;
      4
      5     FUNCTION function_name
      6        RETURN collection_type_name PIPELINED;
      7  END package_name;
      8  /
    Package created.
    SQL> CREATE OR REPLACE PACKAGE BODY package_name
      2  AS
      3     FUNCTION function_name
      4        RETURN collection_type_name PIPELINED
      5     IS
      6     BEGIN
      7        FOR record_name IN (SELECT column_name
      8                            FROM   table_name) LOOP
      9           PIPE ROW (record_name);
    10        END LOOP;
    11
    12        RETURN;
    13     END function_name;
    14  END package_name;
    15  /
    Package body created.
    SQL> VARIABLE variable_name REFCURSOR;
    SQL> BEGIN
      2     OPEN :variable_name FOR
      3        SELECT column_name
      4        FROM   TABLE (package_name.function_name);
      5  END;
      6  /
    PL/SQL procedure successfully completed.
    SQL> PRINT variable_name;
    COLUMN_NAME
    value one
    value two
    SQL>I recommend though that you test this thoroughly. There were bugs with this approach when it was newly introduced that prevented you from dropping the package.

  • Ref Cursors / throwing data into a Ref Cursor as data is fetched

    I was wondering if anyone has executed an SQL statement and as each row is being fetched back from an SQL, doing some data checks and processing to see if the row is valid to return or not, based on the values being fetched in an SQL.
    For example, I'm taking an SQL statement and trying to do some tuning. I have an Exists clause in the Where statement that has a nested sub-query with some parameters passed in. I am attempting to move that statement to a function call in a package (which is called in the SELECT statement). As I fetch each row back, I want to check some values that are Selected and if the values are met, then, I want to execute the function to see if the data exists. If it does exist, then, I want the fetched row returned in the Ref Cursor. If the criteria is met and the row doesn't exist in the function call, then, I don't want the fetched row to return.
    Right now, the data has to be thrown to REF Cursor because it's being outputted to the Java application as a Result Set.
    I've found many statements where you can take a SELECT statement and throw the Results in the Ref Cursor. But, I want to go a step further and before I throw each row in the Ref Cursor, I want to some processing to see if I put the Fetched Row in the Ref Cursor.
    If someone has a better idea to accomplish this, I'm all ears. Like I say, I'm doing this method only for the sake of doing some database tuning and I think this will speed things up. Having the EXISTS clause works and it runs fast from an End-user standpoint but, when it processes on the database with the nested subquery, it is slow.
    Here's an example of something that might be a problem (Notice the nested subquery). I moved the nested subquery to a function call written on the database package and make the call to the procedure/package in the SELECT statement. As I process each row, I want to check some values prior having the function call execute. If it meet some criteria, then the record is Ok to fetch and display in the Ref Cursor. If it does not meet the criteria and goes through the function and doesn't return data, then, I don't want the Fetched row from the main query to return the data.:
    SELECT EMPNO,
    FIRST_NAME,
    LAST_NAME
    FROM EMP E,
    DEPT D
    WHERE E.DEPTNO = D.DEPTNO
    AND EXISTS (SELECT 'X'
    FROM MANAGER M
    WHERE M.MANAGER_ID = E.MANAGER_ID
    AND MANAGER_TYPE IN (SELECT MANAGER_TYPE
    FROM MANAGER_LOOKUP ML WHERE ML.MANAGER_TYPE = M.MANAGER_TYPE))
    Any help or ideas of other things to try is appreciated. Keep in mind that I am returning this data to the Java application so, throwing the data to a Ref Cursor in the PL/SQL is the ideal method.
    Chris

    Ref cursors are not required nor desirable when writing java database application. Cursors are mentioned only once in the JDBC documentation reference guide, in the section "Memory Leaks and Running Out of Cursors".
    In a word cursors are just plain ridiculous, and in fact I never used them in my 15+ years of application development practice:
    http://vadimtropashko.wordpress.com/cursors/

  • Is there a different way to open a cursor for a ref cursor procedure?

    hello everybody
    i have two cursors, cur_a and cur_b, declared somewhere else in my application.
    These two cursors have the same fields, in the same order, and i have to treat both in the same way. So i wrote a routine that gets as input a ref cursor based on the cur_a rowtype, and i am trying to use this routine for both.
    The problem is that i am not able to open outside the routine the cursor in a different way than usual...
    the common method is :
    declare curs ref cursor ...
    begin
    open curs for (select *...)
    end;
    instead i would like to obtain something different
    declare curs ref cursor ...
    begin
    open curs for cur_a
    end;

    hi
    thanks for answering
    i wanted just to give a better idea, anyway you were near to get it.
    the only difference is that the two cursors are not written in dynamic sql, just like strings, but are real cursors.
    anyway, this is the version of the package i need, but i am not able to compile
    (your original code is commented and immediately below there is my code)
    CREATE OR REPLACE PACKAGE BODY mytest
    IS
    --cur_a VARCHAR2(200) := 'SELECT dummy FROM DUAL';
    CURSOR cur_a
    IS
    SELECT dummy
    FROM DUAL;
    --cur_b VARCHAR2(200) := 'SELECT ''fred'' FROM DUAL';
    CURSOR cur_b
    IS
    SELECT 'fred' fred
    FROM DUAL;
    TYPE t_cur_a IS REF CURSOR
    RETURN cur_a%ROWTYPE
    --PROCEDURE routine_a_b (p_cur SYS_REFCURSOR) IS
    PROCEDURE routine_a_b (p_cur t_cur_a)
    IS
    v_x VARCHAR2 (10);
    BEGIN
    LOOP
    FETCH p_cur
    INTO v_x;
    EXIT WHEN p_cur%NOTFOUND;
    DBMS_OUTPUT.put_line (v_x);
    END LOOP;
    END;
    PROCEDURE doit
    IS
    --v_curs SYS_REFCURSOR;
    v_curs t_cur_a;
    BEGIN
    NULL;
    -- open v_curs FOR cur_a;
    OPEN v_curs FOR cur_a;
    routine_a_b (v_curs);
    CLOSE v_curs;
    -- open v_curs FOR cur_b;
    -- routine_a_b(v_curs);
    -- close v_curs;
    END;
    END;
    the error is:
    cursor 'V_CURS' cannot be used in dynamic SQL OPEN statement
    i did read that if use weak ref cursor, it could work, so i declare the ref cursor type in this way:
    TYPE t_cur_a IS REF CURSOR;
    instead than
    TYPE t_cur_a IS REF CURSOR
    RETURN cur_a%ROWTYPE
    what i get is another error (in the open cursor command)
    PLS-00382: expression is of wrong type....
    but if i replace
    OPEN v_curs FOR cur_a;
    with
    OPEN v_curs for select dummy from dual;
    it works... but i already knew it.. :-)
    anyway, i used a work around to resolve it, so it's just philosophy

  • How to read my cursor that is ref cursor returning user defined type

    Hi
    I have types defined as follows:
    TYPE MY_RECORD IS RECORD (
    COL1 TABLE1.COL1%TYPE,
    COL2 TABLE1.COL2%TYPE
    TYPE MY_CURSOR IS REF CURSOR
    RETURN MY_RECORD;This is used as return type in a stored procedure.
    I have a pl/sql block where I make a call to the SP that returns this cursor.
    How can I read individual values being returned from SP?

    SQL> create or replace package pkg
    as
       type my_record is record (col1 emp.empno%type, col2 emp.ename%type);
       type my_cursor is ref cursor
          return my_record;
       procedure p (cur out my_cursor);
    end pkg;
    Package created.
    SQL> create or replace package body pkg
    as
       procedure p (cur out my_cursor)
       as
       begin
          open cur for
             select   empno, ename
               from   emp
              where   rownum <= 2;
       end p;
    end pkg;
    Package body created.
    SQL> declare
       cur     pkg.my_cursor;
       e_rec   pkg.my_record;
    begin
       pkg.p (cur);
       loop
          fetch cur into   e_rec;
          exit when cur%notfound;
          dbms_output.put ('Empno: ' || e_rec.col1);
          dbms_output.put_line ('; Ename: ' || e_rec.col2);
       end loop;
       close cur;
    end;
    Empno: 7369; Ename: SMITH
    Empno: 7499; Ename: ALLEN
    PL/SQL procedure successfully completed.

  • Ref cursor to another Ref cursor.

    Actually I have a ref cursor in a package x which has a procedure y.
    y has 4 parameters like procedure(a,b,c,d in out ref cursor type)
    I have another standalone procedure which has a ref cursor as out parameter and a,b,c as other parameters.
    This stand alone procedure implicitly calls the package procedure as x.y(a,b,c,d) d is a ref cursor defined in the stand alone procedure which is populated by the package's y procedure.
    My issue is that how to populate the standalone procedure's ref cursor with the value of the package's procedure's ref cursor with out using a temporary table?
    Please help me in this regard. It is urgent.

    Actually I have a ref cursor in a package x which has a procedure y.
    y has 4 parameters like procedure(a,b,c,d in out ref cursor type)
    I have another standalone procedure which has a ref cursor as out parameter and a,b,c as other parameters.
    This stand alone procedure implicitly calls the package procedure as x.y(a,b,c,d) d is a ref cursor defined in the stand alone procedure which is populated by the package's y procedure.
    My issue is that how to populate the standalone procedure's ref cursor with the value of the package's procedure's ref cursor with out using a temporary table?
    Please help me in this regard. It is urgent.

  • What is the best way of converting a Top Level VI into a 'sub vi' - or function ( without duplicating programming)

    Hi,
    General question here about design architecture, which i keep running into, but haven't found a really good solution.  If i write a 'Top Level VI' to do something, what is the best way of converting it into a subVI - which is call-able from other VIs, while still allowing the top level VI to have synchronised feedback/indicator updates.
    I guess the point is that when something is a top level VI you write gui logic about what happens when someone clicks buttons or whatever - which you don't want in the 'sub vi' version.
    I did at one point try having a hidden boolean button that was an input to the subVI which would let the VI know if it was supposed to be doing the front panel stuff - or simply running as a subVI.  This isn't really ideal though - since it would be better to be able to hive off the grizzly useful stuff from the fluffy - front panel updating stuff - having them together makes the VIs rather untidy.  More annoyingly though, if you have the front panel version of it running - say waiting for you to hit 'go', it breaks all the other VIs that use it as a sub vi - since they can't compile when a sub vi is already running.
    Another possibility that i tried was to basically duplicate the vi so that there was a backend part, and a front end part - and when i click 'go' the backend part is called as a sub vi.  The problem with this is that it really limits the interface that the user gets - since none of the controls on the front panel update with the results untill the sub vi is over.  I guess again i could solve this by passing references to some of the controls to update them in the subvi - but this doesn't really seem like the ideal situation if the subvi is called by something else without the same types of controls etc.
    One final idea i had was to essentially paste all the controls in the VI into a global variable file, and make the sub vi update them, and the front panel VI read from them.  This seems to 'work' - although clearly it is a work around rather than a proper solution - since i spend loads of time worrying about how i update cluster variables in the global - reading and writing.
    Does anyone have any guidance on what they do to solve this problem?
    JP

    You could run a subvis in a Subpanel on your top level.  Lets you see the current data while the subvi is running.
    --Using LV8.2, 8.6, 2009, 2012--

  • Need Help: Using Ref Cursor in ProC to call a function within a Package

    I'm calling a function within a package that is returning a REF CURSOR.
    As per the Oracle Pro*C Programmer's Guide, I did the following:
    1) declared my cursor with a: EXEC SQL BEGIN DECLARE SECTION and declared the cursor as: SQL_CURSOR my_cursor;
    2) I allocated the cursor as: EXEC SQL ALLOCATE :my_cursor;
    3) Via a EXEC SQL.....END-EXEC begin block
    I called the package function and assign the return value to my cursor
    e.g. my_cursor := package.function(:host1, :host2);
    Now, the only difference between my code and the example given in the Pro*C Programmer's Guide is that the example calls a PROCEDURE within a package that passes back the REF CURSOR as an OUT host variable.
    Whereas, since I am calling a function, the function ASSIGNS the return REF CURSOR in the return value.
    If I say my_cursor := package.function(:host1, :host2); I get a message stating, "PLS-00201: identifier MY_CURSOR" must be declared"
    If I say :my_cursor := package.function(:host1, :host2); I get a message stating, "ORA-01480: trailing null missing from STR bind value"
    I just want to call a package function and assign the return value to a REF CURSOR variable. There must be a way of doing this. I can do this easily in standard PL/SQL. How can this be done in Pro*C ???
    Thanks for any help.

    Folks, I figured it out. For those who may face this problem in the future you may want to take note for future reference.
    Oracle does not allow you to assign the return value of a REF CURSOR from a FUNCTION ( not Procedure - - there is a difference) directly to a host variable. This is the case even if that host variable is declared a CURSOR variable.
    The trick is as follows: Declare the REF CURSOR within the PL/SQL BEGIN Block, using the TYPE statement, that will contain the call to the package function. On the call, you then assign the return REF CURSOR value that the function is returning to your REF CURSOR variable declared in the DECLARE section of the EXEC SQL .... END-EXEC PL/SQL Block.
    THEN, assign the REF CURSOR variable that was populated from the function call to your HOST cursor varaible. Then fetch this HOST Cursor variable into your Host record structure variable. Then you can deference individual fields as need be within your C or C++ code.
    I hope this will help someone facing a deadline crunch. Happy computing !

  • Using ref cursor in where clause

    I have a stored procedure (package procedure) that returns a ref cursor as a parameter. This procedure performs a query and returns the cursor. The procedure calls another stored procedure within the package. This second procedure also returns a ref cursor. I want to do my query on the results of the cursor returned by the second procedure. Hopefully the example below is okay.. "I had to change names to protect the blah blah...."
    For example:
    TYPE out_cursor IS REF CURSOR;
    TYPE IDTable IS TABLE OF table1.ID%TYPE;
    PROCEDURE A
    v_ID IN NUMBER,
    v_Param2 IN NUMBER,
    v_FromClause IN VARCHAR2, -- ignore for now
    v_WhereClause IN VARCHAR2, -- ignore for now
    v_retval OUT NUMBER,
    the_cursor OUT out_cursor
    IS
    v_SQLString VARCHAR2(2048);
    v_cursor1 out_cursor;
    v_tabIDs IDTable;
    BEGIN
    v_SQLString := '';
    packageA.procedureA(v_ID, v_retval, v_cursor1);
    -- this does not work
    -- I get ORA-00942: table or view does not exist
    v_SQLString := 'select distinct * from v_cursor1';
    -- I found this on the message board but
    -- it did not compile.
    -- local collection types not allowed in SQL statements
    FETCH v_cTSFiles BULK COLLECT INTO v_tabIDs;
    v_SQLString := 'select distinct * from table1 WHERE table1.ID in (select * from table(v_tabIDs))';
    OPEN the_cursor FOR v_SQLString;
    END;

    You can use that second technique but as the error message says, "local collection types not allowed in SQL statements". You need to create a schema type instead.
    [sql]
    create or replace type ttab_number is table of number
    create or replace procedure p is
    tab_id ttab_number;
    refcur sys_refcursor;
    begin
    open refcur for
    select user_id
    from all_users;
    fetch refcur bulk collect into tab_id;
    close refcur;
    for rec in (
    select *
    from all_users
    where user_id in (
    select *
    from table(cast(tab_id as ttab_number)))
    ) loop
    dbms_output.put_line(rec.username);
    end loop;
    end;
    [sql]

  • Unit Test Validation for Output Ref Cursor Not Working

    Here is the problem:
    I have a stored procedure as follows:
    CREATE OR REPLACE
    PROCEDURE usp_GetEmployee(
    p_employeeId IN NUMBER,
    cv_employee OUT Sys_RefCursor )
    AS
    BEGIN
    OPEN cv_employee FOR SELECT * FROM employees WHERE employee_id=p_employeeid;
    END usp_GetEmployee;
    For this, I am implementing a unit test.
    * In the "Select Parameters" step, I am unchecking the "Test Result" check box for the cursor OUT variable.
    * In the "Specify Validations" step, I am choosing "Boolean Function" and putting the following PL/SQL code:
    DECLARE
    emp_rec {cv_employee$}%rowtype;
    BEGIN
    FETCH {cv_employee$} INTO emp_rec;
    IF {cv_employee$}%FOUND THEN
    RETURN TRUE;
    ELSE
    RETURN FALSE;
    END IF;
    RETURN TRUE;
    END;
    But, when I try to execute this Test, I get the following error:
    Validation Boolean function failed: Unable to convert <oracle.jdbc.driver.OracleResultSetImpl@4f0617> to REF CURSOR.
    If I run in the debug mode, I get the following content in a dialog box:
    The following procedure was run.
    Execution Call
    BEGIN
    "ARCADMIN"."USP_GETEMPLOYEE"(P_EMPLOYEEID=>:1,
    CV_EMPLOYEE=>:2);
    END;
    Bind variables used
    :1 NUMBER IN 1001
    :2 REF CURSOR OUT (null)
    Execution Results
    ERROR
    CV_EMPLOYEE : Expected: [Any value because apply check was cleared], Received: [EMPLOYEE_ID                             COMMISSION_PCT                          SALARY                                 
    1001                                    0.2                                     8400                                   
    Validation Boolean function failed: Unable to convert <oracle.jdbc.driver.OracleResultSetImpl@31dba0> to REF CURSOR.
    Please suggest how to handle this issue.
    Thanks,
    Rahul

    979635 wrote:
    But, when I try to execute this Test, I get the following error:
    Validation Boolean function failed: Unable to convert <oracle.jdbc.driver.OracleResultSetImpl@4f0617> to REF CURSOR.
    If I run in the debug mode, I get the following content in a dialog box:
    The following procedure was run.
    Execution Call
    BEGIN
    "ARCADMIN"."USP_GETEMPLOYEE"(P_EMPLOYEEID=>:1,
    CV_EMPLOYEE=>:2);
    END;
    Bind variables used
    :1 NUMBER IN 1001
    :2 REF CURSOR OUT (null)
    Try explicity declaring the ref cursor instead of using a bind variable, something like (untested)
    begin
      foo sys_refcurosr;
    begin
      test_procedure(foo);
    end;Alternately, in SQL*PLUS use the DEFINE command to ste a named bind variable to type REFCURSOR and use the named bind variable in your test
    Edited by: riedelme on Jan 23, 2013 7:10 AM

  • Using Ref Cursors as region source

    Is it possible to use a function that returns a ref cursor as a region's source? I asked this question at the end of another thread and got no response so I made this new thread.
    I created an application called 'ref cursor' on apex.oracle.com at
    http://apex.oracle.com/pls/otn/f?p=4550
    Workspace : wc_jason
    username: dev
    password: password
    There is a table named TBL and a function returning a ref cursor name FNC. On the home page there are three regions, one using a sql statement, one using a pl/sql function returning a sql statement, and one that attempts to use a ref cursor. The ref cursor region's condition is set to NEVER because I couldn't get it to work and I wanted to show the page with the two working regions.
    Can I even use a ref cursor in this manor?
    Thanks for the help.

    Heres a quick example I did for you:
    create or replace package pkg_refcursordemo
    as
    type rc_generic is ref cursor;
    rec_emp emp%rowtype;
    type tab_emp is table of emp%rowtype;
    procedure proc_get_emp (
    pi_ename in emp.ename%type
    ,pio_emp_rc in out rc_generic
    function func_get_emp (
    pi_ename in emp.ename%type
    return tab_emp pipelined;
    end pkg_refcursordemo;
    create or replace package body pkg_refcursordemo
    as
    -- Procedure with in out ref cursor parameter
    procedure proc_get_emp (
    pi_ename in emp.ename%type
    ,pio_emp_rc in out rc_generic
    is
    begin
    open pio_emp_rc for
    select empno
    , ename
    , job
    , mgr
    , hiredate
    , sal
    , comm
    , deptno
    from emp
    where ename like pi_ename||'%';
    end proc_get_emp;
    -- Wrapper pipelined function
    function func_get_emp (
    pi_ename in emp.ename%type
    return tab_emp pipelined
    is
    l_rc_generic rc_generic;
    l_rec_emp emp%rowtype;
    begin
    proc_get_emp (
    pi_ename => pi_ename
    ,pio_emp_rc => l_rc_generic
    loop
    fetch l_rc_generic into l_rec_emp;
    exit when l_rc_generic%notfound;
    pipe row ( l_rec_emp );
    end loop;
    close l_rc_generic;
    return;
    end func_get_emp;
    end pkg_refcursordemo;
    create or replace view vw_emp
    as
    select empno
    , ename
    , job
    , mgr
    , hiredate
    , sal
    , comm
    , deptno
    from table ( pkg_refcursordemo.func_get_emp( null ) )
    SQL> select * from vw_emp;
    EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
    7369 SMITH CLERK 7902 17-DEC-80 800 20
    7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
    7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30
    7566 JONES MANAGER 7839 02-APR-81 2975 20
    7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30
    7698 BLAKE MANAGER 7839 01-MAY-81 2850 30
    7782 CLARK MANAGER 7839 09-JUN-81 2450 10
    7788 SCOTT ANALYST 7566 19-APR-87 3000 20
    7839 KING PRESIDENT 17-NOV-81 5000 10
    7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 30
    7876 ADAMS CLERK 7788 23-MAY-87 1100 20
    EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
    7900 JAMES CLERK 7698 03-DEC-81 950 30
    7902 FORD ANALYST 7566 03-DEC-81 3000 20
    7934 MILLER CLERK 7782 23-JAN-82 1300 10
    14 rows selected.
    SQL>
    Whats cool is you can declare the view with an APEX variable in it e.g.
    create or replace view vw_emp
    as
    select empno
    , ename
    , job
    , mgr
    , hiredate
    , sal
    , comm
    , deptno
    from table ( pkg_refcursordemo.func_get_emp( v('P1_ENAME_PARAM' ) )
    /

  • Populate a REF CURSOR from regular cursor...

    Hi all,
    I apologize if the answer to this is somewhere...I've been looking on the web for sometime and can't find an answer to the following problem. I have a Significant Events database that contains network based issues and problems. As problems are detected on the network an SE is issued and published. As the SE records are updated, NEW records are entered into the table and "linked" back to the original. Each update results in a new row. Thus, an SE with two updates would have a total of 3 lines. When the SE gets closed (set the column CLOSED to SYSDATE), only the "original" SE is closed, any updates are left open...aka, the CLOSED column is left null.
    That said, I need a way to get the original and/or latest updated SE rows from the table. Thus, I am trying to use a PL/SQL package. The PL/SQL "must" return a REF CURSOR as the results are being passed to a client process.
    My initial approach was within a PL/SQL procedure, I have an SQL statement that returns the SE originals. Once in that cursor I need to do the following:
    - Attempt to fetch any linked SE rows.
    - if no rows then
    - add the original to the REF CURSOR.
    - else
    - find latest SE update
    - add latest SE update to REF CURSOR.
    - end if
    My Question is : How do I manually "add" a row to a REF CURSOR?
    If this is not possible, is there a way to populate a REF CURSOR from maybe another construct like:
    TYPE ian_se_record is RECORD (
    se_id number
    ,linked_se_id number
    ,submitted date
    ,updated date
    ,closed date
    ,segroup varchar2(150)
    ,incident_start_time varchar2(150)
    ,business_units_affected varchar2(150)
    ,officenum varchar2(1500)
    ,sedetails varchar2(4000)
    TYPE ian_se_table is table of ian_se_record index by binary_integer;
    With the above construct I could:
    - Fill ian_se_table with the process described above.
    - And finally select off ian_se_table into the REF CURSOR?
    Any help would be greatly appreciated,
    adym

    Hi michaels,
    I've put your solution in place, but can't seem to get it to run. The two types were moved out of the package and into real types as you said. Here's the function, for brevity, I've remove some of the less important code:
    function ian_se_fetch return sys_refcursor
    is
        p_csr_events            sys_refcursor;
        cursor csr_items is
            select
                 se_id
        ...removed for brevity...
        /* END : csr_items  */
        ian_se_row     ian_se_record;
        ian_se_tbl     ian_se_table;
        l_lng_index    number;
        l_lng_linked   number;
        l_lng_id       number;
    begin
         * OPEN : Open the main cursor of originals...
        for the_item in csr_items loop
             * CHECK : Check for any updates to the original...
            l_lng_linked := 0;
            select count(*)
            into l_lng_linked
            from sig_se_t src
            where src.linked_se_id = the_item.se_id;
            l_lng_id := 0;    /* reset the se-id    */
            /* SE original...no linked records yet.    */
            if ( l_lng_linked = 0 ) then
                l_lng_id := the_item.se_id;
            /* SE updates...one or more updates are present.    */
            else
                begin
                    select
                         se_id
                    into l_lng_id
                    from sig_se_t src
                    where src.linked_se_id = the_item.se_id
                      and rownum = 1
                    order by updated desc; /* latest update    */
                exception
                    when too_many_rows then
                        l_lng_id := the_item.se_id;
                    when others then
                        l_lng_id := 0;
                end;
            end if;
            if ( l_lng_id != 0 ) then
                select
                     se_id
                    ,linked_se_id
                    ,submitted
                    ,updated
                    ,closed
                    ,segroup
                    ,incident_start_time
                    ,business_units_affected
                    ,officenum || decode( nvl(impact,'1')
                                      ,'1',''
                                      ,decode(impact
                                          ,'NA', ''
                                          ,':' || impact
                                  )                           impact
                    ,sedetails
                into ian_se_row.se_id
                    ,ian_se_row.linked_se_id
                    ,ian_se_row.submitted
                    ,ian_se_row.updated
                    ,ian_se_row.closed
                    ,ian_se_row.segroup
                    ,ian_se_row.incident_start_time
                    ,ian_se_row.business_units_affected
                    ,ian_se_row.officenum
                    ,ian_se_row.sedetails
                from sig_se_t src
                where src.se_id = l_lng_id;
                l_lng_index := nvl(ian_se_tbl.last,0)+1;
                ian_se_tbl(l_lng_index).se_id                   := ian_se_row.se_id;
                ian_se_tbl(l_lng_index).linked_se_id            := ian_se_row.linked_se_id;
                ian_se_tbl(l_lng_index).submitted               := ian_se_row.submitted;
                ian_se_tbl(l_lng_index).updated                 := ian_se_row.updated;
                ian_se_tbl(l_lng_index).closed                  := ian_se_row.closed;
                ian_se_tbl(l_lng_index).segroup                 := ian_se_row.segroup;
                ian_se_tbl(l_lng_index).incident_start_time     := ian_se_row.incident_start_time;
                ian_se_tbl(l_lng_index).business_units_affected := ian_se_row.business_units_affected;
                ian_se_tbl(l_lng_index).officenum               := ian_se_row.officenum;
                ian_se_tbl(l_lng_index).sedetails               := ian_se_row.sedetails;
            end if;
        end loop;
         * REF CURSOR : Open the ref cursor on the dataset...
        if ( nvl(ian_se_tbl.last,0) = 0 ) then
            p_csr_events := null;
        else
            open p_csr_events for
            select *
            from table (cast ( ian_se_tbl as ian_se_table ));
        end if;
        return p_csr_events;
    end;Here's the test. I keep getting the same error ORA-06530:
    SQL> variable v refcursor;
    SQL> exec :v:=pkg_ian.ian_se_fetch;
    BEGIN :v:=pkg_ian.ian_se_fetch; END;
    ERROR at line 1:
    ORA-06530: Reference to uninitialized composite
    ORA-06512: at "N0002501.PKG_IAN", line 131
    ORA-06512: at line 1
    SQL> print v
    ERROR:
    ORA-24338: statement handle not executedOther things I tried:
    - The ian_se_fetch() function was a procedure using an in out parameter...same error.
    - Wrote a small anonymous block and tried to LOOP/FETCH. Same ORA-06530 error.
    P.S. Line 131 of pkg_ian is the SELECT ... INTO ian_se_row.se_id, ...
    Any help would be greatly appreciated,
    tia,
    adym
    Message was edited by:
    alink

  • Ref Cursor from PL/SQL Table

    I'm building a complex report in which the information cames from a lot of tables and needs complex formatting. I'd like to base my report in a table returned by a stored procedure (like you can do in Forms). Is there any way to convert an PL/SQL table in a Ref Cursor?

    Why don't you process the data in procedure and dump into temporary table. And base your report on that temporary table.
    it may simplify your report.
    Atul

  • Dispalying output from a REF CURSOR

    Friends,
    I'm getting my self into indepth pl/sql and need some help from you to clear some basic concepts.
    create table MASTER_TABLE
    street_info varchar2(100),
    property_type varchar2(50) ------- i.e values here would be 'HOME_TABLE' ,'COM_PROP_TABLE' etc
    create table HOME_TABLE
    property_id char(5),
    prop_desc varchar2(100),
    cost varchar2(10),
    location varchar2(100)
    create table COM_PROP_TABLE
    property_id char(5),
    prop_desc varchar2(100),
    cost varchar2(10),
    location varchar2(100)
    I want to use a single procedure to open a weak REF CURSOR variable for the appropriate table based on the street address and display all information from that table.
    Here is what I want to to - execute a stored procedure which accepts 1 'in' paramter and 1 'in out ' parameter.
    IN paramter - accepts street address
    IN OUT paramter - depending on address , if it is related to 'Homes' , it should display all information from the HOME Table, else it will display information from the 'Commerical Property' table.
    create or replace package pack_address_info as
    type v_info_type ref cursor;
    end pack_address_info;
    create or replace procedure schema.sp_home_info(v_add in varchar2,v_show in out v_info_type)
    is
    home_type constant integer :=1;
    commercial_type constant integer :=2;
    cursor show_data_cur is
    select property_type from MASTER TABLE where street_info=v_add;
    var_cursor show_data_cur%rowtype;
    begin
    open show_data_cur;
    fetch show_data_cur into var_cursor;
    close show_data_cur;
    if var_cursor.property_type= HOME_TABLE
    then
    open v_show for
    select * from HOME_TABLE where location=v_add;
    elseif var_cursor.table_name = COM_PROP_TABLE
    then
    open v_show for
    select * from COM_PROP_TABLE where location=v_add;
    end if;
    end schema.sp_home_info;
    I can create the package and the stored proc ... but then ???? i'm stuck ;(
    Now , i don't know how to display the output from the HOME TABLE or the COM_PROP_TABLE depending on what the address is entered? Is this code correct. Can you please help me modify this code so that I can achieve my objective.
    This is an example from the book 'Oracle PL/SQL Programming, 4th Edition' under the 'CURSOR' section - 15.6
    Thanks for the help in advance.

    Here is one sample ->
    satyaki>
    satyaki>select * from v$version;
    BANNER
    Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Prod
    PL/SQL Release 10.2.0.3.0 - Production
    CORE    10.2.0.3.0      Production
    TNS for 32-bit Windows: Version 10.2.0.3.0 - Production
    NLSRTL Version 10.2.0.3.0 - Production
    Elapsed: 00:00:00.02
    satyaki>
    satyaki>
    satyaki>CREATE OR REPLACE PACKAGE aaa_sat     
      2  AS       
      3     TYPE crs IS REF CURSOR RETURN emp%ROWTYPE;        
      4     FUNCTION fc_retcur (e_no IN NUMBER)
      5     RETURN crs;
      6  END aaa_sat;
      7  /
    Package created.
    Elapsed: 00:00:01.03
    satyaki>
    satyaki>
    satyaki>CREATE OR REPLACE PACKAGE BODY aaa_sat     
      2  AS       
      3    FUNCTION fc_retcur (e_no IN NUMBER)
      4    RETURN crs       
      5    IS         
      6      l_crs   crs;       
      7    BEGIN         
      8      OPEN l_crs FOR
      9      SELECT * FROM emp           
    10      WHERE empno = e_no;          
    11     
    12      RETURN l_crs;       
    13    END;
    14  END aaa_sat;
    15  /
    Package body created.
    Elapsed: 00:00:00.18
    satyaki>
    satyaki>
    satyaki>DECLARE       
      2    l_emp_rec   emp%ROWTYPE;       
      3    l_crs       aaa_sat.crs;     
      4  BEGIN       
      5    l_crs := aaa_sat.fc_retcur (7782);        
      6    LOOP          
      7      FETCH l_crs           
      8      INTO l_emp_rec;           
      9        EXIT WHEN l_crs%NOTFOUND;          
    10          DBMS_OUTPUT.put_line (l_emp_rec.ename);     
    11    END LOOP;        
    12    CLOSE l_crs;    
    13  END;
    14  /
    CLARK
    PL/SQL procedure successfully completed.
    Elapsed: 00:00:00.40
    satyaki>
    satyaki>Got Me?
    Regards.
    Satyaki De.

  • Adding ability to use ref cursors in future versions of Apex

    Currently it has been documented that Apex does not play well with ref cursors and how to get around that. Is this a feature that the Apex team is looking into for future versions? Currently we are using Oracle 11g and 1 g with Apex 4.0.2. Your reply is most appreciated.
    JudJasRis

    Hi Tony Miller,
    Thank you for the prompt reply. I see your name in many of the replies in this Apex forum.
    We currently have several package functions that use out ref cursors. We are looking to use the result of that ref cursor for our reports. We have found a way to get around the ref cursor by creating a table collection of the row type and return it in a specific function declaration in a pipelined function. I am fairly new to creating pkgs, functions and specifically pipeline functions as well as learning the many nooks and crannies of Apex. It would be nice to be able to call a predefined ref cursor within Apex. I was just curious if that was a feature that could be developed. Please excuse my lack of knowledge, I am learning though by asking these type of questions.
    Again thank you.
    JudJasRis

Maybe you are looking for