DESCRIBING A REF CURSOR

For debugging purposes, I would like to be able to describe a REF CURSOR returned by a function in a package, using pl/sql.
Can you help me ?

ZlatKo
A brave attempt and well done for putting up with the forum software.
Alas, I can't catually run the code - I get the following error-stack. I'll have another go at it this lunchtime.
If I'm not mistaken your procedure would give us a visual output of the REF CURSOR structure, just like DESC. I think the original poster was after something they could use programmatically inside a PL/SQL procedure to interrogate and process a REF CURSOR with an unknown signature. It would be possible to walk the structure as you do, suck out the values and store them in arrays. Fine. But without knowing the column names how do we know what to do with these values?
At some point the receiving program has to know what the purpose of the REF CURSOR. We can imagine a function that generates a REF CURSOR from one of three queries depending upon the value of an input parameter. Every program which calls that function must pass in that parameter and therefore must know the signature of the REF CURSOR that it gets back.
The idea of a function returning data at its own whim is a bit laughable. Even web services, surely the ultimate expression of the encapsulation paradigm, insist on the publication of a signature - what we have to put in, what we will get back.
Cheers, APC

Similar Messages

  • Describe weak ref cursor

    I want to implement a stored procedure which takes a
    weak ref cursor as one of its IN parameters. In the body
    of the SP I want to analyze the "structure" of the weak
    ref cursor: column names and types.
    Any hints how to do this in PL/SQL?? Of course, in C via OCI
    describing a (weak) ref cursor at run-time is no problem at
    all.
    Tobias.

    it is not possible to fetch into some variable, which doesn't match the structure of the cursor variable.....
    There is one way.....you can discard the first n records while assigning the query to cursor variable....
    Frame ur query that ur going to assocaite to the cursor in the following way....
    select * from (select rownum a, test.* from test) where a > N
    where 'N' is the no of records that u don't want to be in the cursor.....
    if u have doubt in this approach get back to me...

  • How can I iterate over the columns of a REF CURSOR?

    I have the following situation:
    DECLARE
       text   VARCHAR2 (100) := '';
       TYPE gen_cursor is ref cursor;
       c_gen gen_cursor;
       CURSOR c_tmp
       IS
            SELECT   *
              FROM   CROSS_TBL
          ORDER BY   sn;
    BEGIN
       FOR tmp IN c_tmp
       LOOP
          text := 'select * from ' || tmp.table_name || ' where seqnum = ' || tmp.sn;
          OPEN c_gen FOR text;
          -- here I want to iterate over the columns of c_gen
          -- c_gen will have different number of columns every time,
          --        because we select from a different table
          -- I have more than 500 tables, so I cannot define strong REF CURSOR types!
          -- I need something like
          l := c_gen.columns.length;
          for c in c_gen.columns[1]..c_gen.columns[l]
          LOOP
              -- do something with the column value
          END LOOP;
       END LOOP;
    END;As you can see from the comments in the code, I couln'd find any examples on the internet with weak REF CURSORS and selecting from many tables.
    What I found was:
    CREATE PACKAGE admin_data AS
       TYPE gencurtyp IS REF CURSOR;
       PROCEDURE open_cv (generic_cv IN OUT gencurtyp, choice INT);
    END admin_data;
    CREATE PACKAGE BODY admin_data AS
       PROCEDURE open_cv (generic_cv IN OUT gencurtyp, choice INT) IS
       BEGIN
          IF choice = 1 THEN
             OPEN generic_cv FOR SELECT * FROM employees;
          ELSIF choice = 2 THEN
             OPEN generic_cv FOR SELECT * FROM departments;
          ELSIF choice = 3 THEN
             OPEN generic_cv FOR SELECT * FROM jobs;
          END IF;
       END;
    END admin_data;
    /But they have only 3 tables here and I have like 500. What can I do here?
    Thanks in advance for any help!

    The issue here is that you don't know your columns at design time (which is generally considered bad design practice anyway).
    In 10g or before, you would have to use the DBMS_SQL package to be able to iterate over each of the columns that are parsed from the query... e.g.
    CREATE OR REPLACE PROCEDURE run_query(p_sql IN VARCHAR2) IS
      v_v_val     VARCHAR2(4000);
      v_n_val     NUMBER;
      v_d_val     DATE;
      v_ret       NUMBER;
      c           NUMBER;
      d           NUMBER;
      col_cnt     INTEGER;
      f           BOOLEAN;
      rec_tab     DBMS_SQL.DESC_TAB;
      col_num     NUMBER;
      v_rowcount  NUMBER := 0;
    BEGIN
      -- create a cursor
      c := DBMS_SQL.OPEN_CURSOR;
      -- parse the SQL statement into the cursor
      DBMS_SQL.PARSE(c, p_sql, DBMS_SQL.NATIVE);
      -- execute the cursor
      d := DBMS_SQL.EXECUTE(c);
      -- Describe the columns returned by the SQL statement
      DBMS_SQL.DESCRIBE_COLUMNS(c, col_cnt, rec_tab);
      -- Bind local return variables to the various columns based on their types
      FOR j in 1..col_cnt
      LOOP
        CASE rec_tab(j).col_type
          WHEN 1 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_v_val,2000); -- Varchar2
          WHEN 2 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_n_val);      -- Number
          WHEN 12 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_d_val);     -- Date
        ELSE
          DBMS_SQL.DEFINE_COLUMN(c,j,v_v_val,2000);  -- Any other type return as varchar2
        END CASE;
      END LOOP;
      -- Display what columns are being returned...
      DBMS_OUTPUT.PUT_LINE('-- Columns --');
      FOR j in 1..col_cnt
      LOOP
        DBMS_OUTPUT.PUT_LINE(rec_tab(j).col_name||' - '||case rec_tab(j).col_type when 1 then 'VARCHAR2'
                                                                                  when 2 then 'NUMBER'
                                                                                  when 12 then 'DATE'
                                                         else 'Other' end);
      END LOOP;
      DBMS_OUTPUT.PUT_LINE('-------------');
      -- This part outputs the DATA
      LOOP
        -- Fetch a row of data through the cursor
        v_ret := DBMS_SQL.FETCH_ROWS(c);
        -- Exit when no more rows
        EXIT WHEN v_ret = 0;
        v_rowcount := v_rowcount + 1;
        DBMS_OUTPUT.PUT_LINE('Row: '||v_rowcount);
        DBMS_OUTPUT.PUT_LINE('--------------');
        -- Fetch the value of each column from the row
        FOR j in 1..col_cnt
        LOOP
          -- Fetch each column into the correct data type based on the description of the column
          CASE rec_tab(j).col_type
            WHEN 1  THEN DBMS_SQL.COLUMN_VALUE(c,j,v_v_val);
                         DBMS_OUTPUT.PUT_LINE(rec_tab(j).col_name||' : '||v_v_val);
            WHEN 2  THEN DBMS_SQL.COLUMN_VALUE(c,j,v_n_val);
                         DBMS_OUTPUT.PUT_LINE(rec_tab(j).col_name||' : '||v_n_val);
            WHEN 12 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_d_val);
                         DBMS_OUTPUT.PUT_LINE(rec_tab(j).col_name||' : '||to_char(v_d_val,'DD/MM/YYYY HH24:MI:SS'));
          ELSE
            DBMS_SQL.COLUMN_VALUE(c,j,v_v_val);
            DBMS_OUTPUT.PUT_LINE(rec_tab(j).col_name||' : '||v_v_val);
          END CASE;
        END LOOP;
        DBMS_OUTPUT.PUT_LINE('--------------');
      END LOOP;
      -- Close the cursor now we have finished with it
      DBMS_SQL.CLOSE_CURSOR(c);
    END;
    SQL> exec run_query('select empno, ename, deptno, sal from emp where deptno = 10');
    -- Columns --
    EMPNO - NUMBER
    ENAME - VARCHAR2
    DEPTNO - NUMBER
    SAL - NUMBER
    Row: 1
    EMPNO : 7782
    ENAME : CLARK
    DEPTNO : 10
    SAL : 2450
    Row: 2
    EMPNO : 7839
    ENAME : KING
    DEPTNO : 10
    SAL : 5000
    Row: 3
    EMPNO : 7934
    ENAME : MILLER
    DEPTNO : 10
    SAL : 1300
    PL/SQL procedure successfully completed.
    SQL> exec run_query('select * from emp where deptno = 10');
    -- Columns --
    EMPNO - NUMBER
    ENAME - VARCHAR2
    JOB - VARCHAR2
    MGR - NUMBER
    HIREDATE - DATE
    SAL - NUMBER
    COMM - NUMBER
    DEPTNO - NUMBER
    Row: 1
    EMPNO : 7782
    ENAME : CLARK
    JOB : MANAGER
    MGR : 7839
    HIREDATE : 09/06/1981 00:00:00
    SAL : 2450
    COMM :
    DEPTNO : 10
    Row: 2
    EMPNO : 7839
    ENAME : KING
    JOB : PRESIDENT
    MGR :
    HIREDATE : 17/11/1981 00:00:00
    SAL : 5000
    COMM :
    DEPTNO : 10
    Row: 3
    EMPNO : 7934
    ENAME : MILLER
    JOB : CLERK
    MGR : 7782
    HIREDATE : 23/01/1982 00:00:00
    SAL : 1300
    COMM :
    DEPTNO : 10
    PL/SQL procedure successfully completed.
    SQL> exec run_query('select * from dept where deptno = 10');
    -- Columns --
    DEPTNO - NUMBER
    DNAME - VARCHAR2
    LOC - VARCHAR2
    Row: 1
    DEPTNO : 10
    DNAME : ACCOUNTING
    LOC : NEW YORK
    PL/SQL procedure successfully completed.
    SQL>From 11g onwards, you can create your query as a REF_CURSOR, but then you would still have to use the DBMS_SQL package with it's new functions to turn the refcursor into a dbms_sql cursor so that you can then describe the columns in the same way.
    http://technology.amis.nl/blog/2332/oracle-11g-describing-a-refcursor
    Welcome to the issues that are common when you start to attempt to create dynamic code. If your design isn't specific then your code can't be either and you end up creating more work in the coding whilst reducing the work in the design. ;)

  • How to update data returned using REF CURSOR

    Hi all,
    I am trying to update updated data in a gridview but the update button seem to do nothing as i retrieve data using REF CURSOR.
    Let me describe the architecture of my application first. I'm trying to implement best practice whenever possible. I am following the data access tutorial published in www.asp.net , the only difference is that i have an Oracle (10g) database. So I split my application into three layers, data access, business logic, and presentation layer. I'm also writing all queries in an Oracle package.
    So I have my Oracle packages that perform CRUD operations. Then I have an xsd file that define dataTable based on the package procedure. My business logic layer then calls functions defined in the xsd file. And finally a detailsView control that uses an ObjectDataSource to call business logic functions.
    In a nutshell, I am just trying to update records retrieved using REF CURSOR. Your help is very much appreciated. Please let me know if further details are required. Cheers,

    In the DataSet (xsd) where your DataTable is defined, you just need to add additional methods to the TableAdapter to handle insert, update and delete, either with SQL or by mapping to stored procedures.
    Alternatively in code, create an OracleDataAdapter and supply its InsertCommand, UpdateCommand and DeleteCommand.
    David

  • Ref cursors in Database adapter

    Hi,
    Is the database adapter capable of handling ref cursors as the datatype of the output parameters of a pl/sql procedure?
    For instance if I have the following in my package-spec:
    TYPE SomeRecordType IS RECORD
    ( record_pk mut_table.record_pk%TYPE
    , person_nr person_table.person_nr%TYPE
    , field_1 mut_table.field_1%type
    , field_2 mut_table.field_2%type
    , field_3 mut_table.field_3%type
    TYPE SomeCursorType IS REF CURSOR RETURN SomeRecordType;
    PROCEDURE read_records
    ( cursor_out OUT SomeCursorType
    , exception_code OUT number
    , exception_message OUT varchar2
    Can the database adapter call the read_records procedure?
    I've never seen this in any doc. I know it can't handle record types (that is in 10.1.2 it couldn't as far as I know). So I figure that the above is not possible.
    Thanks in advance.
    Regards,
    Martien

    We have successfully used a sys_refcursor OUT parameter for a database procedure call and which is used by a DBAdapter to return a single dataset.
    At the time I remember attempting to use a strongly typed ref cursor as the parameter. I think this is what you are attempting to do. I rejected this approach at the time as I was not able to do this. It was, in our case, as simple as using the system defined ref cursor type (i.e. weakly typed).
    The handling of the returned dataset was not immediately obvious, but can be handled by as fairly simple XSL transformation to a locally defined variable of the requisite xml structure. I won't describe in detail how to do it as it is specific to our process. Suffice to say the transformation loops over all result rows assign via a test to the correct result field in our local variable.
    e.g.
    <xsl:template match="/">
    <ns1:BatchRequest004>
    <xsl:for-each select="/db:OutputParameters/db:P_SCHSHP_REF_CUR/db:Row">
    <ns1:statusRqst>
    <xsl:if test='db:Column/@name = "ID"'>
    <xsl:attribute name="id">
    <xsl:value-of select="db:Column[1.0]"/>
    </xsl:attribute>
    </xsl:if>
    </ns1:statusRqst>
    </xsl:for-each>
    </ns1:BatchRequest004>
    HTH and that I haven't misidentified your problem.

  • VC 7.0 Oracle stored procedures resultset with ref cursor

    Can VC (we are on NW7 SP13) handle Oracle's datatype ref cursor - which is the standard solution in Oracle to return result sets - as the return value of a stored procedure?
    When testing a data service in the VC story board based upon a simple Oracle function like:
    create or replace package pkg_dev
    is
       type t_cursor is ref cursor;
    end;
    create or replace function vc_stub return pkg_dev.t_cursor
    as
    l_cursor pkg_dev.t_cursor;
    begin
    open l_cursor for select ename from emp;
    return l_cursor;
    end;
    (just as example - I know that could be easily retrieved using the BI JDBC connector framework and accessing tables / views)
    I am always running in the "portal request failed ( Could not execute Stored Procedure)" error - so I am not able to use the "add fields" function to bind the output.
    The defaulttrace contains entries like:
    Text: com.sap.portal.vc.HTMLBRunTime
    [EXCEPTION]
    com.sapportals.connector.execution.ExecutionException: Could not execute stored procedure
    Caused by: java.sql.SQLException: Invalid column type
         at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
    We deployed Oracle's own jdbc-driver for Oracle 10g. Using that driver and a portal jdbc connector framework entry the stored procedures of the Oracle database user mapped to the portal user are discovered and available in the "Find Data Services" section.

    We deployed the drivers as described in the HowTo Papers (e.g.Hwo to Configure UD Connect on the J2EE Server for JDBC Access to External Databases). When deploying the drivers you assign a freely definable name for the set of Oracle's jar-files (eg. oracle_10) as library name. Having deployed the drivers in that way only System Definitions via BI JDBC connector framework were working. With a little help from SAP Support (call lasted more than 2 months till a very capable member of the support team made things working in a very short time) we got the portal jdbc connection with Oracle's jar-files working:
    Here are instructions how to add reference:
    1. Connect to the j2ee using telnet, e.g in the cmd window type:
    telnet <host> <port> + 8, enter uid and pwd of j2ee admin.
    2. jump 0
    3. add deploy
    4. change_ref -m com.sapportals.connectors.database <your lib name>       <your lib name = oracle_10>
    Trying to manually add this reference in visual admin connector container for JDBCFactory failed - reference could be added and saved, but then disappeared (at least in NW7 with SP12). Adding the reference as described above solved the problem.

  • Bind Variables in ref cursor

    Version details
    BANNER
    Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
    PL/SQL Release 10.2.0.4.0 - Production
    CORE    10.2.0.4.0      Production
    TNS for Solaris: Version 10.2.0.4.0 - Production
    NLSRTL Version 10.2.0.4.0 - ProductionBelow is the procedure where I'm using ref cursor
    CREATE OR REPLACE PROCEDURE ref_sample
    p_account_nbr     in     varchar2,
    p_ref_out          out     sys_refcursor
    IS
    BEGIN
         OPEN p_ref_out FOR
         SELECT     account_nbr,status,(
                                            CASE
                                                 WHEN status = 'Pending' THEN
                                                      req_mail_date
                                                 WHEN status IN ('Rejected','Approved') THEN
                                                      NVL(verified_mail_date,req_mail_date)
                                            END
                                            )req_mail_date ,
                                                 CASE
                                                      WHEN status = 'Pending' THEN
                                                           NULL
                                                      WHEN status IN ('Rejected','Approved') THEN
                                                           NVL(verified_user_id,req_user_id)
                                                 END
                                            )req_user_id
         FROM     X_tbl
         WHERE     account_nbr IN p_account_nbr
                   AND TRUNC(upload_date) = TRUNC(SYSDATE)
         ORDER BY upload_date DESC ;
    END;
    /My input parameter p_account_nbr looks like ('a1','a2','a3')
    Now,after knowing the importance of bind variables I'd like to make use of them in the above ref cursor.
    But,here my input parameter is a string of varying length..either I've to go for the approach suggested here
    http://asktom.oracle.com/pls/asktom/f?p=100:11:3667281145899708::::P11_QUESTION_ID:110612348061
    or
    http://www.dba-oracle.com/t_cursor_sharing.htm
    I'm not much clear with the first approach,so I'm thinking of to modify my procedure as below
    CREATE OR REPLACE PROCEDURE ref_sample
    p_account_nbr     in     varchar2,
    p_ref_out          out     sys_refcursor
    IS
    BEGIN
         alter session set cursor_sharing=force;
         OPEN p_ref_out FOR
         SELECT     account_nbr,status,(
                                            CASE
                                                 WHEN status = 'Pending' THEN
                                                      req_mail_date
                                                 WHEN status IN ('Rejected','Approved') THEN
                                                      NVL(verified_mail_date,req_mail_date)
                                            END
                                            )req_mail_date ,
                                                 CASE
                                                      WHEN status = 'Pending' THEN
                                                           NULL
                                                      WHEN status IN ('Rejected','Approved') THEN
                                                           NVL(verified_user_id,req_user_id)
                                                 END
                                            )req_user_id
         FROM     X_tbl
         WHERE     account_nbr IN p_account_nbr
                   AND TRUNC(upload_date) = TRUNC(SYSDATE)
         ORDER BY upload_date DESC ;
         alter session set cursor_sharing=exact;     
    END;
    /Please let me know if the above modified code is fine or should I use bind variables??Also let me know better approach of both.

    The correct way to do this is use an array type for the input values as in this example.
    SQL> create or replace procedure p
      2      (
      3      p_values sys.odcivarchar2list,
      4      c out sys_refcursor
      5      ) as
      6  begin
      7      open c for
      8         select object_name, owner, object_type
      9         from all_objects
    10         where object_name in (select column_value from table(p_values));
    11  end;
    12  /
    Procedure created.
    SQL> var c refcursor
    SQL> exec p (sys.odcivarchar2list('DUAL','USER_VIEWS'), :c)
    PL/SQL procedure successfully completed.
    SQL> print c
    OBJECT_NAME                    OWNER                          OBJECT_TYPE
    DUAL                           SYS                            TABLE
    DUAL                           PUBLIC                         SYNONYM
    USER_VIEWS                     SYS                            VIEW
    USER_VIEWS                     PUBLIC                         SYNONYM
    SQL> exec p (sys.odcivarchar2list('DUAL','USER_VIEWS','ALL_OBJECTS','ALL_SOURCE'), :c)
    PL/SQL procedure successfully completed.
    SQL> print c
    OBJECT_NAME                    OWNER                          OBJECT_TYPE
    DUAL                           SYS                            TABLE
    DUAL                           PUBLIC                         SYNONYM
    ALL_OBJECTS                    SYS                            VIEW
    ALL_OBJECTS                    PUBLIC                         SYNONYM
    USER_VIEWS                     SYS                            VIEW
    USER_VIEWS                     PUBLIC                         SYNONYM
    ALL_SOURCE                     SYS                            VIEW
    ALL_SOURCE                     PUBLIC                         SYNONYM
    8 rows selected.
    SQL>That and other methods are described here.
    http://tkyte.blogspot.com/2006/06/varying-in-lists.html
    You would not use dynamic SQL.

  • 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

  • Different error messages from different env while fetching ref cursor

    Hi<br>
    I have a package where i need to call one of the procedure.I this <br>
    procedure i am returning a refcursor as out parameter.Before returning refcursor i <br>
    am doing i am checking a condition if it is satisfied then I am saying return or else<br>
    it will proceed and refcursor is assigned for out parameter.So i am speakig about <br>
    the condition where i am exiting from procedure before refcursor parameter is <br>
    assigned .And later i am tring to fetch from that cursor .So i am getting different <br>
    kinds of errors which i described as follows <br>
    <br>
    <br>
    So If execute that procedure from sqlplus uing <br>
    <br>
    <br>
    var m ref cursor<br>
    DECLARE<br>
    Y NUMBER;<br>
    Z NUMBER;<br>
    A NUMBER;<br>
    BEGIN<br>
    A:=campa.dtl_inq(2,100070875,'R',Y,Z,:M);<br>
    END;<br>
    <br>
    Then if say<br>
    Print m<br>
    It gives <br>
    <br>
    ORA-24338: statement handle not executed<br>
    <br>
    And if i execute this using vb application <br>
    <br>
    I am getting following error <br>
    <br>
    ORA-01023: Cursor context not found (Invalid cursor number)<br>
    <br>
    So i am serching the reason for different errors<br>
    <br>
    Regards<br>
    vamsi krishna<br>

    The error depends on exactly what OCI calls the client software makes in accessing this invalid (null) ref cursor variable.
    It would seem that SQL*Plus makes different calls than what your code and Visual Basic does - thus the different error messages returned by the two applications.

  • SQR - Ref Cursor

    <p>I am trying to call an Oracle stored procedure within SQR thatreturns a ref cursor.  I am able to successfully do this onlyif I run the program as the schema owner.  I read that SQRneeds to be able to do a describe on the stored procedure in orderfor the program to work.  I can do a describe but only if Iinclude the schema owner (ex. schema_owner.stored_procedure). So, logically, I tried to add the schema owner to the storedprocedure name within sqr.  When I do this I get the error(SQR 3918) Missing Stored Procedure or Function.</p><p> </p><p>Here is the syntax below:</p><p>execute on-error=ora_err do=print_plan_type<br> @#retVal=HRIS.HRIS_HRS_DS_PACKAGE.Get_Plan_Type_List@rc01=$planCursor OUT<br> INTO &pc_ext_app_id varchar2(3)</p><p> </p><p>Any thoughts on how I can get SQR to recognize the schemaowner?<br></p>

    Here's a link:
    PL/SQL Users Guide and Reference
    cheers,
    Anthony

  • Is it possible to ref cursor(result set) as in parameter to procedure/funct

    Hi,
    I am getting a resultset/ref cursor from the Java side to the procedure/function as in parameter. Is this possible in oracle 10g.
    If yes can body send the links/suggestions describing some examples.
    Thanks,

    I am getting a resultset/ref cursor from the Java
    side to the procedure/function as in parameter. Is
    this possible in oracle 10g. It is possible, but it sounds like you have your application design entirely backwards.
    A ref cursor is designed to be used to pass a result set from a stored procedure to a client or calling application.
    So while you could use a screwdriver to hammer in a nail, you probably would not want to.

  • Odd error while opening a ref cursor

    Hi.
    I have a procedure in a package that has both in and out parameters. One of those out parameters is a ref cursor. The procedure creates a dynamic query and then executes it, then it opens the cursor:
    PROCEDURE PROC(
    A IN VARCHAR2,
    B IN VARCHAR2,
    C OUT TYPES.cursorType; --(TYPES is a package whose only use is to declare a cursor type)
    ) IS
    --DECLARATIONS
    OPEN C FOR 'SELECT A, B, C, D...';
    END;
    When I execute the package in an anonymous block it throws the error:
    ORA-00938: not enough arguments for function, just in the line where the cursor is being opened.
    Any ideas?

    is everything defined correctly?
    create or replace package types  as
      type cursorType is ref cursor;
    end types;
    SQL> set serveroutput on
    SQL> declare
      2 
      3    ref_C types.cursorType;
      4   
      5    v_a varchar2(1);
      6    v_b varchar2(1);
      7    v_c varchar2(1);
      8    v_d varchar2(1);
      9   
    10    procedure Proc (a in varchar2
    11                   ,b in varchar2
    12                   ,C out types.cursorType) as
    13 
    14      begin
    15        open C for 'select :1, :2, ''c'', ''d'' from dual' using a, b;
    16    end  Proc;
    17  begin
    18 
    19 
    20    Proc('a', 'b', ref_C);
    21   
    22    fetch ref_C into v_a, v_b, v_c, v_d;
    23    if (ref_C%found) then
    24      dbms_output.put_line(v_a);
    25      dbms_output.put_line(v_b);
    26      dbms_output.put_line(v_c);
    27      dbms_output.put_line(v_d);
    28    end if;
    29   
    30   
    31  end;
    32  /
    a
    b
    c
    dP;
    Edited by: bluefrog on Feb 18, 2010 6:07 PM

  • Ref Cursor and For Loop

    The query below will return values in the form of
    bu     seq     eligible
    22     2345     Y
    22     2345     N
    22     1288     N
    22     1458     Y
    22     1458     N
    22     1234     Y
    22     1333     N
    What I am trying to accomplish is to loop through the records returned.
    for each seq if there is a 'N' in the eligible column return no record for that seq
    eg seq 2345 has 'Y' and 'N' thus no record should be returned.
    seq 1234 has only a 'Y' then return the record
    seq 1333 has 'N' so return no record.
    How would I accomplish this with a ref Cursor and pass the values to the front end application.
    Procedure InvalidNOs(io_CURSOR OUT T_CURSOR)
         IS
              v_CURSOR T_CURSOR;
         BEGIN
    OPEN v_CURSOR FOR
    '     select bu, seq, eligible ' ||
    '     from (select bu, seq, po, tunit, tdollar,eligible,max(eligible) over () re ' ||
    '          from (select bu, seq, po, tunit, tdollar,eligible ' ||
    '          from ( ' ||
    '          select bu, seq, po, tunit, tdollar, eligible, sum(qty) qty, sum(price*qty) dollars ' ||
    '               from ' ||
    '               ( select /*+ use_nl(t,h,d,s) */ ' ||
    '               h.business_unit_id bu, h.edi_sequence_id seq, d.edi_det_sequ_id dseq, ' ||
    '                    s.edi_size_sequ_id sseq, h.po_number po, h.total_unit tUnit, h.total_amount tDollar, ' ||
    '                    s.quantity qty, s.unit_price price,' ||
    '               (select (case when count(*) = 0 then ''Y'' else ''N'' end) ' ||
    '          from sewn.NT_edii_po_det_error ' ||
    '          where edi_det_sequ_id = d.edi_det_sequ_id ' ||
    '               ) eligible ' ||
    '     from sewn.nt_edii_purchase_size s, sewn.nt_edii_purchase_det d, ' ||
    '     sewn.nt_edii_purchase_hdr h, sewn.nt_edii_param_temp t ' ||
    '     where h.business_unit_id = t.business_unit_id ' ||
    '     and h.edi_sequence_id = t.edi_sequence_id ' ||
    '     and h.business_unit_id = d.business_unit_id ' ||
    '     and h.edi_sequence_id = d.edi_sequence_id ' ||
    '     and d.business_unit_id = s.business_unit_id ' ||
    '     and d.edi_sequence_id = s.edi_sequence_id ' ||
    '     and d.edi_det_sequ_id = s.edi_det_sequ_id ' ||
    '     ) group by bu, seq, po, tunit, tdollar, eligible ' ||
    '     ) ' ||
    '     group by bu, seq, po, tunit, tdollar, eligible)) ';
              io_CURSOR := v_CURSOR;
    END     InvalidNOs;

    One remark why you should not use the assignment between ref cursor
    variables.
    (I remembered I saw already such thing in your code).
    Technically you can do it but it does not make sense and it can confuse your results.
    In the opposite to usual variables, when your assignment copies value
    from one variable to another, cursor variables are pointers to the memory.
    Because of this when you assign one cursor variable to another you just
    duplicate memory pointers. You don't copy result sets. What you do for
    one pointer is that you do for another and vice versa. They are the same.
    I think the below example is self-explained:
    SQL> /* usual variables */
    SQL> declare
      2   a number;
      3   b number;
      4  begin
      5   a := 1;
      6   b := a;
      7   a := a + 1;
      8   dbms_output.put_line('a = ' || a);
      9   dbms_output.put_line('b = ' || b);
    10  end;
    11  /
    a = 2
    b = 1
    PL/SQL procedure successfully completed.
    SQL> /* cursor variables */
    SQL> declare
      2   a sys_refcursor;
      3   b sys_refcursor;
      4  begin
      5   open a for select empno from emp;
      6   b := a;
      7   close b;
      8 
      9   /* next action is impossible - cursor already closed */
    10   /* a and b are the same ! */
    11   close a;
    12  end;
    13  /
    declare
    ERROR at line 1:
    ORA-01001: invalid cursor
    ORA-06512: at line 11
    SQL> declare
      2   a sys_refcursor;
      3   b sys_refcursor;
      4   vempno emp.empno%type;
      5 
      6  begin
      7   open a for select empno from emp;
      8   b := a;
      9 
    10   /* Fetch first row from a */
    11   fetch a into vempno;
    12   dbms_output.put_line(vempno);
    13 
    14   /* Fetch from b gives us SECOND row, not first -
    15      a and b are the SAME */
    16 
    17   fetch b into vempno;
    18   dbms_output.put_line(vempno);
    19 
    20 
    21  end;
    22  /
    7369
    7499
    PL/SQL procedure successfully completed.Rgds.
    Message was edited by:
    dnikiforov

  • Dynamic sql and ref cursors URGENT!!

    Hi,
    I'm using a long to build a dynamic sql statement. This is limited by about 32k. This is too short for my statement.
    The query results in a ref cursor.
    Does anyone have an idea to create larger statement or to couple ref cursors, so I can execute the statement a couple of times and as an result I still have one ref cursor.
    Example:
    /* Determine if project is main project, then select all subprojects */
    for i in isMainProject loop
    if i.belongstoprojectno is null then
    for i in ProjectSubNumbers loop
    if ProjectSubNumbers%rowcount=1 then
    SqlStatement := InitialStatement || i.projectno;
    else
    SqlStatement := SqlStatement || PartialStatement || i.projectno;
    end if;
    end loop;
    else
    for i in ProjectNumber loop
    if ProjectNumber%rowcount=1 then
    SqlStatement := InitialStatement || i.projectno;
    else
    SqlStatement := SqlStatement || PartialStatement || i.projectno;
    end if;
    end loop;
    end if;
    end loop;
    /* Open ref cursor */
    open sql_output for SqlStatement;
    Thanks in advance,
    Jeroen Muis
    KCI Datasystems BV
    mailto:[email protected]

    Example for 'dynamic' ref cursor - dynamic WHERE
    (note that Reports need 'static' ref cursor type
    for building Report Layout):
    1. Stored package
    CREATE OR REPLACE PACKAGE report_dynamic IS
    TYPE type_ref_cur_sta IS REF CURSOR RETURN dept%ROWTYPE; -- for Report Layout only
    TYPE type_ref_cur_dyn IS REF CURSOR;
    FUNCTION func_dyn (p_where VARCHAR2) RETURN type_ref_cur_dyn;
    END;
    CREATE OR REPLACE PACKAGE BODY report_dynamic IS
    FUNCTION func_dyn (p_where VARCHAR2) RETURN type_ref_cur_dyn IS
    ref_cur_dyn type_ref_cur_dyn;
    BEGIN
    OPEN ref_cur_dyn FOR
    'SELECT * FROM dept WHERE ' | | NVL (p_where, '1 = 1');
    RETURN ref_cur_dyn;
    END;
    END;
    2. Query PL/SQL in Reports
    function QR_1RefCurQuery return report_dynamic.type_ref_cur_sta is
    begin
    return report_dynamic.func_dyn (:p_where);
    end;
    Regards
    Zlatko Sirotic
    null

  • ORA-01008 with ref cursor and dynamic sql

    When I run the follwing procedure:
    variable x refcursor
    set autoprint on
    begin
      Crosstab.pivot(p_max_cols => 4,
       p_query => 'select job, count(*) cnt, deptno, row_number() over (partition by job order by deptno) rn from scott.emp group by job, deptno',
       p_anchor => Crosstab.array('JOB'),
       p_pivot  => Crosstab.array('DEPTNO', 'CNT'),
       p_cursor => :x );
    end;I get the following error:
    ^----------------
    Statement Ignored
    set autoprint on
    begin
    adsmgr.Crosstab.pivot(p_max_cols => 4,
    p_query => 'select job, count(*) cnt, deptno, row_number() over (partition by
    p_anchor => adsmgr.Crosstab.array('JOB'),
    p_pivot => adsmgr.Crosstab.array('DEPTNO', 'CNT'),
    p_cursor => :x );
    end;
    ORA-01008: not all variables bound
    I am running this on a stored procedure as follows:
    create or replace package Crosstab
    as
        type refcursor is ref cursor;
        type array is table of varchar2(30);
        procedure pivot( p_max_cols       in number   default null,
                         p_max_cols_query in varchar2 default null,
                         p_query          in varchar2,
                         p_anchor         in array,
                         p_pivot          in array,
                         p_cursor in out refcursor );
    end;
    create or replace package body Crosstab
    as
    procedure pivot( p_max_cols          in number   default null,
                     p_max_cols_query in varchar2 default null,
                     p_query          in varchar2,
                     p_anchor         in array,
                     p_pivot          in array,
                     p_cursor in out refcursor )
    as
        l_max_cols number;
        l_query    long;
        l_cnames   array;
    begin
        -- figure out the number of columns we must support
        -- we either KNOW this or we have a query that can tell us
        if ( p_max_cols is not null )
        then
            l_max_cols := p_max_cols;
        elsif ( p_max_cols_query is not null )
        then
            execute immediate p_max_cols_query into l_max_cols;
        else
            RAISE_APPLICATION_ERROR(-20001, 'Cannot figure out max cols');
        end if;
        -- Now, construct the query that can answer the question for us...
        -- start with the C1, C2, ... CX columns:
        l_query := 'select ';
        for i in 1 .. p_anchor.count
        loop
            l_query := l_query || p_anchor(i) || ',';
        end loop;
        -- Now add in the C{x+1}... CN columns to be pivoted:
        -- the format is "max(decode(rn,1,C{X+1},null)) cx+1_1"
        for i in 1 .. l_max_cols
        loop
            for j in 1 .. p_pivot.count
            loop
                l_query := l_query ||
                    'max(decode(rn,'||i||','||
                               p_pivot(j)||',null)) ' ||
                                p_pivot(j) || '_' || i || ',';
            end loop;
        end loop;
        -- Now just add in the original query
        l_query := rtrim(l_query,',')||' from ( '||p_query||') group by ';
        -- and then the group by columns...
        for i in 1 .. p_anchor.count
        loop
            l_query := l_query || p_anchor(i) || ',';
        end loop;
        l_query := rtrim(l_query,',');
        -- and return it
        execute immediate 'alter session set cursor_sharing=force';
        open p_cursor for l_query;
        execute immediate 'alter session set cursor_sharing=exact';
    end;
    end;
    /I can see from the error message that it is ignoring the x declaration, I assume it is because it does not recognise the type refcursor from the procedure.
    How do I get it to recognise this?
    Thank you in advance

    Thank you for your help
    This is the version of Oracle I am running, so this may have something to do with that.
    Oracle9i Enterprise Edition Release 9.2.0.8.0 - Production
    With the Partitioning, OLAP and Oracle Data Mining options
    JServer Release 9.2.0.8.0 - Production
    I found this on Ask Tom (http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:3027089372477)
    Hello, Tom.
    I have one bind variable in a dynamic SQL expression.
    When I open cursor for this sql, it gets me to ora-01008.
    Please consider:
    Connected to:
    Oracle8i Enterprise Edition Release 8.1.7.4.1 - Production
    JServer Release 8.1.7.4.1 - Production
    SQL> declare
      2    type cur is ref cursor;
      3    res cur;
      4  begin
      5    open res for
      6    'select * from (select * from dual where :p = 1) connect by 1 = 1'
      7    using 1;
      8  end;
      9  /
    declare
    ERROR at line 1:
    ORA-01008: not all variables bound
    ORA-06512: at line 5
    SQL> declare
      2    type cur is ref cursor;
      3    res cur;
      4  begin
      5    open res for
      6    'select * from (select * from dual where :p = 1) connect by 1 = 1'
      7    using 1, 2;
      8  end;
      9  /
    PL/SQL procedure successfully completed.
    And if I run the same thing on 10g -- all goes conversely. The first part runs ok, and the second
    part reports "ORA-01006: bind variable does not exist" (as it should be, I think). Remember, there
    is ONE bind variable in sql, not two. Is it a bug in 8i?
    What should we do to avoid this error running the same plsql program code on different Oracle
    versions?
    P.S. Thank you for your invaluable work on this site.
    Followup   June 9, 2005 - 6pm US/Eastern:
    what is the purpose of this query really?
    but it would appear to be a bug in 8i (since it should need but one).  You will have to work that
    via support. I changed the type to tarray to see if the reserved word was causing a problem.
    variable v_refcursor refcursor;
    set autoprint on;
    begin 
         crosstab.pivot (p_max_cols => 4,
                 p_query => 
                   'SELECT job, COUNT (*) cnt, deptno, ' || 
                   '       ROW_NUMBER () OVER ( ' || 
                   '          PARTITION BY job ' || 
                   '          ORDER BY deptno) rn ' || 
                   'FROM   emp ' ||
                   'GROUP BY job, deptno',
                   p_anchor => crosstab.tarray ('JOB'),
                   p_pivot => crosstab.tarray ('DEPTNO', 'CNT'),
                   p_cursor => :v_refcursor);
    end;
    /Was going to use this package as a stored procedure in forms but I not sure it's going to work now.

Maybe you are looking for

  • F-51: Balancing field "Profit Center" in line item 001 not filled

    Hi, When trying to clear the Vendors using F-51, I'm getting a messages saying:'Balancing field "Profit Center" in line item 001 not filled'. When I simulate I'm able to see the profit centers getting picked up against all the other line items, excep

  • Problem with GET table

    Dear Friends, I have upload one program for customer ageing report. In that there is statements like GET LFA1, GET BSIK etc. when i save and check it throughs an error that "lfa1 is not defined for the current logical database'. but these statements

  • Exporting to quicktime for web

    Can you tell me the best quality setting when exporting a clip from final cut for use on a website. The clip has been green screened with the filter and it looks clear in the viewer, but when watching it in quicktime and on the web, its fuzzy? Any id

  • Expressions editing bug (os x)

    Hi there when editing an expression, whenever using copy/paste, or dragging a selection to reposition it in the expression, after exiting the editing some of the text disappears. if valid, the expression actually works, but i can see only a portion o

  • I canu00B4t see enhancement

    Hello all, I am trying to see one enhancement that I created in the system but I can´t see the code. I go to SW84 transaction, put the name and appears, but when I click on button to see the code, I can´t see nothing... What can I do? Thanks in advan