Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Declaring SYS_REFCURSOR and ROWTYPE in stored procedure

So I have a stored procedure ONE

create or replace PROCEDURE ONE
(
   A in number
   B in number
   ...
   ZZ out SYS_REFCURSOR
) IS
  SOME_OTHER_STUFF
BEGIN
   ...
END

This returns a sys_refcursor with some data I need. I then have a stored procedure TWO

create or replace PROCEDURE TWO
(
   A in number
   B in number
   ...
   ZZ out SYS_REFCURSOR
) IS
     Count_Records Sys_Refcursor;
     l_rec Count_Records%rowtype;
BEGIN
    /* get some data from the ONE stored procedure to use on this procedure*/
    ONE(A,B,...Count_Records)

    Loop
       fetch count_records into l_rec;
       Exit When count_records%Notfound;
       If  l_rec.TT_RAW > MAX_RECORDS  Then
         Raise To_Many_Results;
       End If;
    End Loop;

END

I'm getting an error when I try to declare the rowtype l_rec Count_Records%rowtype;

How can I declare this variable? The problem is that TT_RAW which is the column I'm trying to get is a SUM and the cursor is not mapped to any table it includes a lot of calculation.

Thanks

like image 294
JSantos Avatar asked Dec 19 '25 14:12

JSantos


1 Answers

The whole point of sys_refcursor is that it's dynamically defined. The rowtype declaration, on the other hand has to be static (if it's not, the compiler can't tell if the fields referenced from it are valid). This is the definition of a use case where you should be defining your own strongly typed ref cursor, instead of using sys_refcursor.

Below is a very simple example:

CREATE OR REPLACE PACKAGE BODY rc_example IS
   PROCEDURE two (a IN NUMBER, b IN NUMBER);
END rc_example;
/

CREATE OR REPLACE PACKAGE BODY rc_example IS
   TYPE one_record IS RECORD (FIRST_VALUE VARCHAR2 (10));

   TYPE one_cursor IS REF CURSOR
      RETURN one_record;

   --Could alternately be declared using a table's rowtype:
   --TYPE one_cursor is ref cursor return some_table%rowtype;

   PROCEDURE one (a IN NUMBER, b IN NUMBER, zz OUT one_cursor) IS
   BEGIN
      OPEN zz FOR SELECT 'test' FROM DUAL;
   END one;

   PROCEDURE two (a IN NUMBER, b IN NUMBER) IS
      count_records SYS_REFCURSOR;
      l_rec count_records%ROWTYPE;
   BEGIN
      one (a, b, count_records);

      LOOP
         FETCH count_records INTO l_rec;

         DBMS_OUTPUT.put_line (l_rec.FIRST_VALUE);
         EXIT WHEN count_records%NOTFOUND;
      END LOOP;
   END two;
END rc_example;
/
like image 96
Allan Avatar answered Dec 21 '25 07:12

Allan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!