The RETURNING INTO clause allows us to return column values for rows affected by DML statements. The returned data could be a single column, multiple columns or expressions.
When we insert data using a sequence to generate our primary key value, we can return the primary key value as follows.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
SET SERVEROUTPUT ON DECLARE l_id t1.id%TYPE; BEGIN INSERTINTO t1 VALUES (t1_seq.nextval, 'FOUR') RETURNING id INTO l_id; COMMIT;
DBMS_OUTPUT.put_line('ID='|| l_id); END; / ID=4
PL/SQLprocedure successfully completed.
SQL>
The syntax is also available for update and delete statements.
SET SERVEROUTPUT ON DECLARE l_id t1.id%TYPE; BEGIN UPDATE t1 SET description = description WHERE description ='FOUR' RETURNING id INTO l_id;
DBMS_OUTPUT.put_line('UPDATE ID='|| l_id);
DELETEFROM t1 WHERE description ='FOUR' RETURNING id INTO l_id;
DBMS_OUTPUT.put_line('DELETE ID='|| l_id);
COMMIT; END; / UPDATE ID=4 DELETE ID=4
PL/SQLprocedure successfully completed.
SQL>
# DML Affecting Multiple Rows - Returning Into Collections
When DML affects multiple rows we can still use the RETURNING INTO clause, but if we want values returned for all rows touched we must return the values into a collection using the BULK COLLECT clause.
SET SERVEROUTPUT ON DECLARE TYPE t_tab ISTABLEOF t1.id%TYPE; l_tab t_tab; BEGIN UPDATE t1 SET description = description RETURNING id BULK COLLECTINTO l_tab;
FOR i IN l_tab.first .. l_tab.last LOOP DBMS_OUTPUT.put_line('UPDATE ID='|| l_tab(i)); END LOOP;
SET SERVEROUTPUT ON DECLARE TYPE t_desc_tab ISTABLEOF t1.description%TYPE; TYPE t_tab ISTABLEOF t1%ROWTYPE; l_desc_tab t_desc_tab := t_desc_tab('FIVE', 'SIX', 'SEVEN'); l_tab t_tab; BEGIN
FORALL i IN l_desc_tab.first .. l_desc_tab.last INSERTINTO t1 VALUES (t1_seq.nextval, l_desc_tab(i)) RETURNING id, description BULK COLLECTINTO l_tab;
FOR i IN l_tab.first .. l_tab.last LOOP DBMS_OUTPUT.put_line('INSERT ID='|| l_tab(i).id || ' DESC='|| l_tab(i).description); END LOOP;
SET SERVEROUTPUT ON DECLARE TYPE t_tab ISTABLEOF t1.id%TYPE; l_tab t_tab; BEGIN EXECUTE IMMEDIATE 'UPDATE t1 SET description = description RETURNING id INTO :l_tab' RETURNING BULK COLLECTINTO l_tab;
FOR i IN l_tab.first .. l_tab.last LOOP DBMS_OUTPUT.put_line('UPDATE ID='|| l_tab(i)); END LOOP;
# DML Affecting Multiple Rows - Returning With Aggregations
We are not forced to use collections when using the RETURNING INTO clause with DML that affects multiple rows. If the output is aggregated, it can be placed into a regular variable. Thanks to Oren Nakdimon for making me aware of this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
SET SERVEROUTPUT ON DECLARE l_max_id NUMBER; BEGIN UPDATE t1 SET description = description RETURNING MAX(id) INTO l_max_id;
RETURNING INTO can not use for INSERT INTO ... SELECT ...
1 2 3 4 5
CREATEOR REPLACE TRIGGER YSC.som_hub_dn_upload_header_bi1 BEFORE INSERTON som_hub_dn_upload_header FOREACHROWWHEN (NEW.header_id isnull) BEGIN SELECT som_hub_dn_upload_header_s.NEXTVAL INTO :NEW.header_id FROM DUAL; END;