Victor
Victor

Reputation: 17097

Populate an oracle collection type using a SYS_REFCURSOR and close the cursor

In my stored procedure, I have a code snippet like this:

OPEN p_result FOR
SELECT *
FROM TABLE (CAST ( l_data AS Rpt_mapping_TableType));
COMMIT;

p_result is an IN OUT parameter of type SYS_REFCURSOR.Rpt_mapping_TableType is a user defined collection type. So this cursor will just populate the Rpt_mapping_TableType and then the program that calls this proc will read the results from Rpt_mapping_TableType. My question is what is the use of COMMIT in this snippet? The code author says it is a way of closing the cursor. Is it right? My other question is if I just want to populate the collection , do I even need to do OPEN p_result FOR. After all I am not reading anything from the cursor so :

SELECT *  FROM TABLE (CAST ( l_data AS Rpt_mapping_TableType));

should suffice.

No?

Upvotes: 1

Views: 1611

Answers (1)

Jon Heller
Jon Heller

Reputation: 36817

A commit will not close a cursor. If it did, then your code wouldn't work. (Although it could unlock rows from a FOR UPDATE, causing other problems.) Here's an example of a commit not closing a cursor:

SQL> variable test refcursor
SQL> begin
  2  open :test for select 1 from dual;
  3  end;
  4  /

PL/SQL procedure successfully completed.

SQL> commit;

Commit complete.

SQL> print test;

         1
----------
         1

SQL>

If you just want to populate a collection, you're probably better off using something like SELECT ... BULK COLLECT INTO ... instead. (And possibly using a LIMIT.) The keyword CURSOR is frequently over-used. Unless you're passing data to another program, implicit cursors and bulk collects are usually much simpler and faster.

Upvotes: 1

Related Questions