Skip to Main Content

SQL & PL/SQL

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

BULK COLLECT/SYS_REFCURSOR question

donovan7800Feb 24 2012 — edited Feb 28 2012
Hi,

I have some procedures that currently handle bulk input parameters using nested tables. All was fine and well (we could even consume it out of straight Java/JDBC) until we had to provide an implementation that would work with proprietary web methods. Apparently they can only use cursors so now I have to change the input paramters. I have a small POC that is giving me issues. Procedure compiles but execution fails:
CREATE OR REPLACE TYPE test_type IS OBJECT
(
    tid     NUMBER,
    tdesc   VARCHAR2(50)
);
CREATE OR REPLACE TYPE test_tab_type IS TABLE OF test_type;

CREATE OR REPLACE PROCEDURE test_bulk_collect(p_ref_cursor IN OUT SYS_REFCURSOR)
AS
    l_recs test_tab_type := test_tab_type();
BEGIN

    FETCH p_ref_cursor                     -- run-time error happens here when in debug mode
    BULK COLLECT INTO l_recs;  
    
    FOR i IN l_recs.FIRST .. l_recs.LAST
    LOOP
        l_recs(i).tdesc := 'updated' || i;   -- the real procedure will do some heavy biz logic for each row.
    END LOOP;
    
    OPEN p_ref_cursor FOR
    SELECT *
    FROM TABLE(l_recs);
    
END;
My execution test:
DECLARE
    v_test_tab_type     test_tab_type := test_tab_type();
    v_row               test_type;
    v_ref_cursor        SYS_REFCURSOR;
BEGIN
    
    -- populate nested table
    v_test_tab_type.EXTEND(2);
    v_test_tab_type(1) := test_type(1, '');
    v_test_tab_type(2) := test_type(2, '');
    
    -- populate SYS_REFCURSOR
    OPEN v_ref_cursor FOR
    SELECT *
    FROM TABLE(v_test_tab_type);
    
    -- call procedure
    test_bulk_collect(p_ref_cursor => v_ref_cursor);
       
    -- display output values
    LOOP
        FETCH v_Ref_Cursor INTO v_Row;
        DBMS_OUTPUT.PUT_LINE('tid: ' || v_Row.tid || '  tdesc: ' || v_Row.tdesc);
        EXIT WHEN v_ref_cursor%notfound;
    END LOOP;
    CLOSE v_ref_cursor;
    
END;
Here is the error:
ORA-06504: PL/SQL: Return types of Result Set variables or query do not match
ORA-06512: at "TEST_BULK_COLLECT", line 6
ORA-06512: at line 18
06504. 00000 -  "PL/SQL: Return types of Result Set variables or query do not match"
*Cause:    Number and/or types of columns in a query does not match declared
           return type of a result set  variable, or declared types of two Result
           Set variables do not match.
*Action:   Change the program statement or declaration. Verify what query the variable
           actually refers to during execution.
Do I have to break up the parameters into a separate IN and OUT cursor? I can't think of anything else that would be wrong since the columns match up...
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Mar 27 2012
Added on Feb 24 2012
8 comments
5,453 views