创建插入记录的过程,如果异常,过程需要从异常行开始

时间:2016-02-03 19:39:15

标签: sql oracle plsql procedure

我需要编写将记录插入多个表的过程,例如我有3个表,

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 

使用现有表的结构创建中间表。

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); 

我的插入记录的程序

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; 

第1点:上述过程只执行一次插入查询1 SOURCE_TEMP获取值。 第1点:TARGET_TEMP和NEWID_TEMP未插入值或未执行。

我的问题:我可以用'--insert query 2'行的起点重新执行这个程序吗?

因为我在新表中插入了100个表记录,如果在这段时间内插入了50个表,如果我在proc执行中遇到任何错误,剩下的50个表需要插入值,因为我没有希望删除前50个表插入的值,这将是耗时的活动。 ORACLE中有这种类型的问题可以使用任何保存点或布尔概念(可在java和unix中使用)。如果是,如何使用此功能?

4 个答案:

答案 0 :(得分:0)

CREATE OR REPLACE PROCEDURE insert_sql 
is
 v_new_rec_count int:=0; 
BEGIN 
select count(*) 
into v_new_rec_count 
from (
select * FROM SOURCE
minus
select * FROM SOURCE_TEMP
) ;
If v_new_rec_count >0 then
INSERT INTO SOURCE_TEMP SELECT * FROM SOURCE; --insert query 1 
Commit;--permanently save the records in table and it wont be rolledback after -             --      any subsequent failure.
v_new_rec_count  :=0;
end if;


select count(*) 
into v_new_rec_count 
from (
select * FROM TARGET
minus
select * FROM TARGET_TEMP
) ;
If v_new_rec_count >0 then
INSERT INTO TARGET_TEMP SELECT * FROM TARGET; --insert query 2 
Commit;--permanently save the records in table and it wont be rolledback after -             --      any subsequent failure.
v_new_rec_count  :=0;
end if;


select count(*) 
into v_new_rec_count 
from (
select * FROM NEWID
minus
select * FROM NEWID_TEMP
) ;
If v_new_rec_count >0 then
INSERT INTO NEWID_TEMP SELECT * FROM NEWID; --insert query 2 
Commit;--permanently save the records in table and it wont be rolledback after -             --      any subsequent failure.
v_new_rec_count  :=0;
end if;

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

答案 1 :(得分:0)

感谢所有人的支持

我创建了Proc,最后我得到了PLSQL-PROCEDURE来执行我的概念。

create TABLE FLAG 
( 
FLAG VARCHAR2(6) 
); 

INSERT INTO FLAG VALUES('PASS01');

答案 2 :(得分:0)

创建或替换程序insert_sql

IS

x int;

FLG FLAG.FLAG%type;

BEGIN

dbms_output.enable;

从FLAG中选择FLAG进入FLG;

如果FLG ='PASS01'那么

DBMS_OUTPUT.PUT_LINE( 'PASS01');

DELETE FROM SOURCE_TEMP;

DBMS_OUTPUT.PUT_LINE( 'SOURCE_TEMP-DELETED');

INSERT INTO SOURCE_TEMP SELECT * FROM SOURCE;

DBMS_OUTPUT.PUT_LINE( 'SOURCE_TEMP插入');

UPDATE FLAG SET FLAG ='PASS02';

DBMS_OUTPUT.PUT_LINE( 'PASS02更新');

从FLAG中选择FLAG进入FLG;

DBMS_OUTPUT.PUT_LINE( 'PASS02-SELECT');

COMMIT;

结束if;

如果FLG ='PASS02'那么

DBMS_OUTPUT.PUT_LINE( 'PASS02');

从TARGET_TEMP删除;

DBMS_OUTPUT.PUT_LINE( 'TARGET_TEMP-DELETED');

INSERT INTO TARGET_TEMP SELECT * FROM TARGET;

DBMS_OUTPUT.PUT_LINE( 'TARGET_TEMP-INSERTEDD');

UPDATE FLAG SET FLAG ='PASS03';

DBMS_OUTPUT.PUT_LINE( 'PASS03更新');

从FLAG中选择FLAG进入FLG;

DBMS_OUTPUT.PUT_LINE( 'PASS03-FLG');

COMMIT;

结束if;

- x:= 1/0;

如果FLG ='PASS03'那么

DBMS_OUTPUT.PUT_LINE( 'PASS03');

DELETE FROM NEWID_TEMP;

DBMS_OUTPUT.PUT_LINE( 'NEWID_TEMP-DELETED');

INSERT INTO NEWID_TEMP SELECT * FROM NEWID;

DBMS_OUTPUT.PUT_LINE( 'NEWID_TEMP-INSERTEDD');

UPDATE FLAG SET FLAG ='PASS01';

DBMS_OUTPUT.PUT_LINE( 'PASS01更新');

从FLAG中选择FLAG进入FLG;

DBMS_OUTPUT.PUT_LINE( 'PASS01-FLG');

COMMIT;

结束if;

NO_DATA_FOUND,然后DBMS_OUTPUT.PUT_LINE('NO_DATA_FOUND!')的异常;

其他时间DBMS_OUTPUT.PUT_LINE('错误消息:!'|| SQLERRM ||'Sql代码:'|| SQLCODE);

END;

答案 3 :(得分:0)

    CREATE OR REPLACE PROCEDURE insert_sql 
is
 v_new_rec_count int:=0; 
 CURSOR cur_src
 IS
 SELECT * FROM SOURCE ;
 TYPE cur_src_typ IS TABLE OF cur_src%ROWTYPE;
  cur_src_tbl cur_src_typ;

 CURSOR cur_newid
 IS
 SELECT * FROM newid ;
 TYPE cur_newid_typ IS TABLE OF cur_src%ROWTYPE;
 cur_newid_tbl cur_newid_typ;

 CURSOR cur_target
 IS
 SELECT * FROM target ;
 TYPE cur_target_typ IS TABLE OF cur_src%ROWTYPE;
 cur_target_tbl cur_target_typ;

BEGIN 
cur_src_tbl :=cur_src_tbl();
cur_newid_tbl :=cur_newid_tbl();
cur_target_tbl :=cur_target_tbl();


OPEN cur_src;
LOOP
FETCH cur_src BULK COLLECT INTO cur_src_tbl LIMIT 500;
EXIT WHEN cur_src_tbl.count =0;
FOR i IN cur_src LOOP
 BEGIN
 INSERT INTO SOURCE_TEMP VALUES(cur_src(i).sort_code,cur_src(i).flag);
 COMMIT;
 EXCEPTION 
 WHEN OTHERS THEN NULL;
 END;
 CLOSE cur_src;

OPEN cur_target;
LOOP
FETCH cur_target BULK COLLECT INTO cur_target_tbl LIMIT 500;
EXIT WHEN cur_target.count =0;
FOR i IN cur_target_tbl LOOP
 BEGIN
 INSERT INTO target_temp VALUES(cur_target_tbl(i).sort_code,cur_target_tbl(i).target_sort_code);
 COMMIT;
 EXCEPTION 
 WHEN OTHERS THEN NULL;
 END;
 CLOSE cur_newid;

 OPEN cur_newid;
LOOP
FETCH cur_newid BULK COLLECT INTO cur_newid_tbl LIMIT 500;
EXIT WHEN cur_newid_tbl.count =0;
FOR i IN cur_newid_tbl LOOP
 BEGIN
 INSERT INTO newid_TEMP VALUES(cur_newid_tbl(i).sort_code,cur_newid_tbl(i).flag);
 COMMIT;
 EXCEPTION 
 WHEN OTHERS THEN NULL;
 END;
 CLOSE cur_newid;

END;