Skip to Main Content
  • Questions
  • CREATE PROCEDURE for INSERTING THE RECORDS, IF EXCEPTION, PROCEDURE NEEDS START FROM EXCEPTION LINE

Breadcrumb

Question and Answer

Chris Saxon

Thanks for the question, Partheeban.

Asked: February 03, 2016 - 7:01 am UTC

Last updated: February 04, 2016 - 7:09 am UTC

Version: Oracle 11g

Viewed 10K+ times! This question is

You Asked

Hi Connor McDonald,

I need to write the procedure for inserting the records in to multiple tables, for example I am HAVING here 3 table,

CREATE TABLE SOURCE
(
SORT_CODE NUMBER,
FLAG CHAR(1)
);

INSERT INTO SOURCE VALUES(605096,5);

INSERT INTO SOURCE VALUES(605097,5);

INSERT INTO SOURCE VALUES(605098,5);

INSERT INTO SOURCE VALUES(605099,5);

INSERT INTO SOURCE VALUES(605100,5);

INSERT INTO SOURCE VALUES(605101,6);

INSERT INTO SOURCE VALUES(605102,6);

INSERT INTO SOURCE VALUES(605103,6);

INSERT INTO SOURCE VALUES(605104,6);

INSERT INTO SOURCE VALUES(605105,6);


SQL> SELECT * FROM SOURCE;

SORT_CODE F
---------- -
605096 5
605097 5
605098 5
605099 5
605100 5
605101 6
605102 6
605103 6
605104 6
605105 6

10 rows selected.


CREATE TABLE TARGET
(
SORT_CODE NUMBER,
TARGET_SORT_CODE NUMBER
);

Table created.


--INSERT 5 VALUES

INSERT INTO TARGET VALUES(605101,189873);

INSERT INTO TARGET VALUES(605102,189874);

INSERT INTO TARGET VALUES(605103,189875);

INSERT INTO TARGET VALUES(605104,189876);

INSERT INTO TARGET VALUES(605105,'');


SELECT * FROM TARGET;

SORT_CODE TARGET_SORT_CODE
---------- ----------------
605101 189873
605102 189874
605103 189875
605104 189876
605105


CREATE TABLE NEWID
(
SORT_CODE NUMBER,
ID_SCODE NUMBER
);

Table created.


--INSERT 2 VALUES


INSERT INTO TARGET VALUES(605103,189875);

INSERT INTO TARGET VALUES(605104,189876);


SELECT * FROM NEWID;

SORT_CODE ID_SCODE
---------- ----------------
605103 189875
605104 189876


--Creating intermediate tables with existing table's structure.
CREATE TABLE SOURCE_TEMP AS (SELECT * FROM SOURCE WHERE 1=2);

CREATE TABLE TARGET_TEMP AS (SELECT * FROM TARGET WHERE 1=2);

CREATE TABLE NEWID_TEMP AS (SELECT * FROM NEWID WHERE 1=2);

--MY Procedure for inserting the records
CREATE OR REPLACE PROCEDURE insert_sql
is
BEGIN

DELETE FROM SOURCE_TEMP;
INSERT INTO SOURCE_TEMP SELECT * FROM SOURCE; --insert query 1

DELETE FROM TARGET_TEMP;
INSERT INTO TARGET_TEMP SELECT * FROM TARGET; --insert query 2
--due to some network issue or table error this procedure GOT EXEPCTION here and above insert query 2(TARGET_TEMP) and below --insert query 3(NEWID_TEMP) is not inserted the values or not executed procedure is came out from this line.

DELETE FROM NEWID_TEMP;
INSERT INTO NEWID_TEMP SELECT * FROM NEWID; --insert query 3

EXCEPTION
WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('ERROR');
END;

Point 1: The above procedure is executed only one insert query 1 SOURCE_TEMP is got the values.
Point 1: TARGET_TEMP and NEWID_TEMP is not inserted the values or not execute.

MyQues: can I able to re-execute this procedure with starting point of '--insert query 2' line?

becoz I am inserting the 100 tables records in new tables, if 50 tables are inserted the values during this time if i am getting any error in the proc execution, remaining 50 tables needs to insert the values, for I dont wish to delete the previous 50 tables inserted the values it will be the time consuming activity. any save point concepts is there for this type of issue in ORACLE (which is available in java and unix)

Thanks
Partheeban.J


and Chris said...

Thanks for the test case. I'm not able to reproduce an exception though. Are there constraints on the tables, or was the exception a network/system issue?

In any case Oracle doesn't have an in-built "rerun, continuing from X if there was an exception". You need to code this manually. e.g. by adding boolean parameters insert_source, insert_target, etc.

You can then code if blocks to skip over the statements you want to bypass:

if insert_source then
  delete ...
  insert ...
end if;

if target_source then
  delete ...
  insert ...
end if;


You'll have to update your client code to figure out what does/doesn't need redoing.

Chris

Rating

  (2 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

CREATE PROCEDURE for INSERTING THE RECORDS, IF EXCEPTION, PROCEDURE NEEDS START FROM EXCEPTION LINE

Partheeban J, February 03, 2016 - 7:51 pm UTC

Thanks Chris Saxon,

How we can use this boolean in this Proc, becaz I can get any type of error, (network error, constraint error)

All tables are executing from Source database only.

boolean is only TRUE, FALSE and NULL.

insert_source(true or false), insert_target(true or false), what type of BOOLEAN VALUE WHICH I NEED TO GIVE HERE TO figure out my proc.

Thanks
Partheeban.J
Chris Saxon
February 04, 2016 - 7:09 am UTC

One of the truly awesome things about PL/SQL is that a routine becomes a single logical unit of work. So as long as you allow the exceptions to propagate up, the transactional integrity is taken care of for you.

eg

SQL> create table T ( id int, x varchar2(40));

Table created.

SQL>
SQL> create or replace
  2  procedure P is
  3     x int;
  4  begin
  5     insert into T values (1,'first row');
  6
  7     insert into T values (2,'second row');
  8
  9     --
 10     -- this will make the procedure crash
 11     --
 12     x := 1/0;
 13
 14     insert into T values (3,'third row');
 15
 16     insert into T values (4,'fourth row');
 17  end;
 18  /

Procedure created.

SQL>
SQL> insert into T values ( 0, 'an uncommitted row before we ran P');

1 row created.

SQL>
SQL> select * from T;

        ID X
---------- ----------------------------------------
         0 an uncommitted row before we ran P

SQL>
SQL>
SQL> exec P
BEGIN P; END;

*
ERROR at line 1:
ORA-01476: divisor is equal to zero
ORA-06512: at "MCDONAC.P", line 11
ORA-06512: at line 1


SQL>
SQL> select * from T;

        ID X
---------- ----------------------------------------
         0 an uncommitted row before we ran P


CREATE PROCEDURE for INSERTING THE RECORDS, IF EXCEPTION, PROCEDURE NEEDS START FROM EXCEPTION LINE

Partheeban J, February 08, 2016 - 5:24 pm UTC

Thanks Chris Saxon,

Finally I got PLSQL-PROCEDURE to execute my concepts.

create TABLE FLAG
(
FLAG VARCHAR2(6)
);

INSERT INTO FLAG VALUES('PASS01');


CREATE OR REPLACE PROCEDURE p
IS
x int;
FLG FLAG.FLAG%type;
BEGIN
SELECT FLAG INTO FLG FROM FLAG;
if FLG='PASS01' then
DBMS_OUTPUT.PUT_LINE('PASS01');
DELETE FROM TTT WHERE CASE_ID=1001;
DBMS_OUTPUT.PUT_LINE('PASS01-DELETED');
INSERT INTO TTT SELECT * FROM UID_CASE WHERE CASE_ID=1001;
DBMS_OUTPUT.PUT_LINE('PASS01-INSERTED');
UPDATE FLAG SET FLAG='PASS02';
DBMS_OUTPUT.PUT_LINE('PASS02-UPDATED');
SELECT FLAG INTO FLG FROM FLAG;
COMMIT;
end if;
if FLG='PASS02' then
DBMS_OUTPUT.PUT_LINE('PASS02');
DELETE FROM TTT WHERE CASE_ID=1002;
DBMS_OUTPUT.PUT_LINE('PASS02-DELETED');
INSERT INTO TTT SELECT * FROM UID_CASE WHERE CASE_ID=1002;
DBMS_OUTPUT.PUT_LINE('PASS02-INSERTED');
UPDATE FLAG SET FLAG='PASS03';
DBMS_OUTPUT.PUT_LINE('PASS03-UPDATED');
SELECT FLAG INTO FLG FROM FLAG;
COMMIT;
end if;
x :=1/0; --error will occur here and next time if I remove this line, my procedure will start it from IF FLG='PASS03' then
if FLG='PASS03' then
DBMS_OUTPUT.PUT_LINE('PASS03');
DELETE FROM TTT WHERE CASE_ID=1003;
DBMS_OUTPUT.PUT_LINE('PASS03-DELETED');
INSERT INTO TTT SELECT * FROM UID_CASE WHERE CASE_ID=1003;
DBMS_OUTPUT.PUT_LINE('PASS03-INSERTED');
UPDATE FLAG SET FLAG='PASS04';
DBMS_OUTPUT.PUT_LINE('PASS04-UPDATED');
SELECT FLAG INTO FLG FROM FLAG;
COMMIT;
end if;
if FLG='PASS04' then
DBMS_OUTPUT.PUT_LINE('PASS04');
DELETE FROM TTT WHERE CASE_ID=1004;
DBMS_OUTPUT.PUT_LINE('PASS04-DELETED');
INSERT INTO TTT SELECT * FROM UID_CASE WHERE CASE_ID=1004;
DBMS_OUTPUT.PUT_LINE('PASS04-INSERTED');
UPDATE FLAG SET FLAG='PASS05';
DBMS_OUTPUT.PUT_LINE('PASS05-UPDATED');
SELECT FLAG INTO FLG FROM FLAG;
COMMIT;
end if;
if FLG='PASS05' then
DBMS_OUTPUT.PUT_LINE('PASS05');
DELETE FROM TTT WHERE CASE_ID=1005;
DBMS_OUTPUT.PUT_LINE('PASS05-DELETED');
INSERT INTO TTT SELECT * FROM UID_CASE WHERE CASE_ID=1005;
DBMS_OUTPUT.PUT_LINE('PASS05-INSERTED');
UPDATE FLAG SET FLAG='PASS01';
DBMS_OUTPUT.PUT_LINE('PASS01-UPDATED');
SELECT FLAG INTO FLG FROM FLAG;
COMMIT;
end if;
EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('NO_DATA_FOUND!');
WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('Error Message: !'|| SQLERRM ||' Sql Code: ' || SQLCODE);
END;

exec p;

SQL> EXEC P;
PASS01
PASS01-DELETED
PASS01-INSERTED
PASS02-UPDATED
PASS02
PASS02-DELETED
PASS02-INSERTED
PASS03-UPDATED
Error Message: !ORA-01476: divisor is equal to zero Sql Code: -1476

PL/SQL procedure successfully completed.

SQL> EXEC P;
PASS03
PASS03-DELETED
PASS03-INSERTED
PASS04-UPDATED
PASS04
PASS04-DELETED
PASS04-INSERTED
PASS05-UPDATED
PASS05
PASS05-DELETED
PASS05-INSERTED
PASS01-UPDATED

PL/SQL procedure successfully completed.

SQL>

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library