Best way to check if SYS_REFCURSOR is empty

I have a cursor with values from a select and i want to do something after depending if i had any row found or none.

recs_Table SYS_REFCURSOR;

begin

    open recs_Table for
       select * from table1, table2;


    if recs_Table%found then
        --do this
    else
        --do that
    end if;

end;

This doesnt seem to work, any help?Ty

Upvotes: 5

Views: 32812

Answers (6)

This work for me :D

    IF(MYCURSOR%ROWCOUNT = 0)THEN
         DO SOMETHING ...
    END IF;-- fixed syntax error

Upvotes: 0

Naveen
Naveen

Reputation: 1

 --TO GET COUNT ON REF_SYSCURSOR BEFORE SENDING TO THE OUTPUT
 SET SERVEROUTPUT ON;
DECLARE
    recs_table SYS_REFCURSOR;
    curid           NUMBER;
BEGIN
    OPEN recs_table FOR SELECT
                            'ABC' name1,
                            'DEF' name2,
                            'GHI' name3
                        FROM
                            dual
                        WHERE 1=0;
curid := DBMS_SQL.TO_CURSOR_NUMBER (recs_table);
DBMS_OUTPUT.PUT_LINE('curid :'||curid);
LOOP
    IF DBMS_SQL.FETCH_ROWS(curid) > 0 THEN
        DBMS_OUTPUT.PUT_LINE('DATA FOUND IN CURSOR :'||curid);
    EXIT;
    ELSE
        DBMS_OUTPUT.PUT_LINE('DATA NOT FOUND IN CURSOR :'||curid);
    EXIT;
    END IF;
END LOOP;
DBMS_SQL.CLOSE_CURSOR(curid);
END;
/

Upvotes: 0

Ricardo Arana
Ricardo Arana

Reputation: 63

You can also select a count into a variable by executing select count() query prior to opening a cursor and then checking it as follows:

select count(*) into v_count from table1;
if v_count>0 then
    --do this
    open my_cursor for 
        select var1,var2,var3 from table1;
    fetch etc.
else
    --do that
end if;

Upvotes: 0

create or replace procedure pro_sample(recs_Table out SYS_REFCURSOR) is
    begin
       open recs_Table for
           select a,b,c,d from table1, table2;
    end;

create or replace function haveRows_pro_sample is
sam sys_refcursor;
var varchar(200);
varOut number:=0;
    begin
        pro_sample(sam);
        fetch sam into var,var,var,var;   
        if sam%found then
          varOut :=1;
        end if;
        return varOut;
    end;

Upvotes: 0

Smart003
Smart003

Reputation: 1119

we use two procedures to execute the result

create or replace procedure pro_sample(recs_Table out SYS_REFCURSOR) is

    begin
       open recs_Table for
           select * from table1, table2;
    end;

this above procedure will be used to open a cursor

create or replace procedure pro_sample(recs_Table out SYS_REFCURSOR) is
   sam sys_refcursor;
   var number;
              -- if you have any variables then declare them
  begin
    pro_sample(sam);
    fetch sam into var;
    if sam%found then
       --do this
        else
       --do that
    end if;
    close sam;
 end;

the above procedure will help you to know whether the cursor contains rows or not

Upvotes: 0

You need to execute a FETCH against the cursor prior to using the %FOUND attribute. Change your code to something like

DECLARE
  recs_Table SYS_REFCURSOR;
  nTable_1_value  NUMBER;
  nTable_2_value  NUMBER;
begin

    open recs_Table for
       select * from table1, table2;


    FETCH recs_Table INTO nTable_1_value, nTable_2_value;

    if recs_Table%found then
        --do this
    else
        --do that
    end if;

end;

Note that the way you'll probably need to add variables to the INTO clause of the FETCH statement, one for each column in TABLE1 and TABLE2. Note also that the way this cursor is written you'll probably get more rows returned than you might expect; because there is no join criteria specified you'll get what's called a Cartesian join, where each row in TABLE1 is joined to each row in TABLE2 - thus, the number of rows you'll get back is (# of rows in TABLE1) * (# of rows in TABLE2).

A potentially simpler way to do this would be to use a cursor FOR loop, as follows:

DECLARE
  bData_found  BOOLEAN := FALSE;
begin
  FOR aRow IN (select * from table1, table2)
  LOOP
    -- If the program gets here, it means a row was fetched

    -- do this

    bData_found := TRUE;

    EXIT;  -- if you only care if data was found and don't want to 
           -- process all the rows
  END LOOP;

  IF NOT bData_found THEN
    -- do that
  END IF;
end;

Share and enjoy.

Upvotes: 5

Related Questions