I am working on a procedure to automate some inserts based on an IN parameter. I also want to know if the inserts fail or not, so I created an exception that returns me a ‘FAIL’ if any error occurs. I have the procedure completed, and I’m sure it will do the inserts if I just run the procedure, but I need to use this inside of another one, therefore I need to be able to access the status of the inserts. Usually I would select * into variable, but because I have inserts in my procedure I get errors about using inserts inside of a query. Please help me find a way to be able to call my procedure to know if they fail and act accordingly.
Here is a sample set of data and a sample procedure with similar functionality to mine:
create table datatable(val1 INT, val2 INT, val3 INT); create procedure insert_datatable(n in int, status out varchar2) is status varchar2 := 'good'; begin for i in 1.. n loop insert into datatable(val1,val2,val3) values (1,2,n) end loop commit; exception when others then rollback; status := 'fail' return status end;
The above proc would then need to be called to 1. do the inserts and 2. tell me if they failed. I tried (without success):
select insert_datatable into insert_status from dual;
Advertisement
Answer
You don’t need to declare a status
variable local to the procedure; its already declared as an OUT
parameter. You also should leave the COMMIT
and ROLLBACK
statements to the block where you call the procedure; this allows multiple procedures to be called in one transaction and then can commit them all or roll them all back. You also don’t use RETURN
statements in a procedure.
CREATE PROCEDURE insert_datatable( n in int, status out varchar2 ) IS BEGIN FOR i IN 1 .. n LOOP insert into datatable(val1,val2,val3) values (1,2,n); END LOOP; status := 'good'; EXCEPTION WHEN others THEN status := 'fail'; END; /
Then you can call it using PL/SQL (you can’t use procedures in a query, you’d need a function for that):
DECLARE p_status VARCHAR2(20); BEGIN insert_datatable( n => 3, status => p_status ); DBMS_OUTPUT.PUT_LINE( p_status ); END; /
Which outputs good
and puts values into the table:
VAL1 | VAL2 | VAL3 ---: | ---: | ---: 1 | 2 | 3 1 | 2 | 3 1 | 2 | 3
db<>fiddle here