Reputation: 3995
My stored-procedure is looping executing different statements. I want to handle the following situations:
no_data_found
), I want to quietly skip the rest of the loop (continue
).continue
);The code looks like:
...
LOOP
stmt := 'select * ......';
BEGIN
EXECUTE IMMEDIATE stmt;
EXCEPTION
WHEN NO_DATA_FOUND THEN NULL;
WHEN OTHERS THEN
dbms_out.put_line(stmt || ': ' || SQLCODE);
CONTINUE;
END;
dbms_out.put_line('Found! Use: ' || stmt);
END LOOP;
The above elicits no errors, but the Found
-line is printed for every loop-iteration, including for statements, that yield no results...
Why is the CONTINUE
-directive ignored -- am I wrong expecting the directive to be obeyed for any exception -- be it NO_DATA_FOUND
or anything else?
Upvotes: 0
Views: 179
Reputation: 50077
In your exception block, the action for your NO_DATA_FOUND
handler is NULL - so it executes the NULL statement (i.e. does nothing) and falls out of the BEGIN-END block, hitting the dbms_out.put_line('Found! Use: ' || stmt);
statement. The only handler which will execute CONTINUE;
is the WHEN OTHERS
.
One way to get the behavior you describe is to do a SELECT COUNT(*)...
into a numeric variable and then just check to see how many rows are returned:
DECLARE
csr SYS_REFCURSOR;
nCount NUMBER;
BEGIN
LOOP
stmt := 'SELECT COUNT(*) FROM (SELECT * from ... WHERE ...)';
OPEN csr FOR stmt;
FETCH csr INTO nCount;
CLOSE csr;
IF nCount > 0 THEN
dbms_out.put_line('Found! Use: ' || stmt);
ELSE
dbms_out.put_line(stmt || ': ' || SQLCODE);
END IF;
END LOOP;
END;
Of course this is not really valid as there's no way for the value of stmt
to change, but I suspect your "real" code handles that.
Upvotes: 1