【问题标题】:Create procedure for inserting the records, if exception, procedure needs start from exception line创建插入记录的过程,如果出现异常,过程需要从异常行开始
【发布时间】:2016-05-13 04:29:28
【问题描述】:

我需要编写将记录插入多个表的过程,例如我有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. 

插入 5 个值

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. 

插入 2 个值

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 中可用)。如果是的话如何使用这个功能?

【问题讨论】:

  • 请修改您的问题标题以使其成为正确的大小写(即关闭您的大写锁定)。
  • 停止呐喊——我们不是聋子
  • "任何保存点或布尔概念都适用于 ORACLE 中的此类问题" - 是的。令人惊讶的是,对应的命令被称为savepointdocs.oracle.com/database/121/SQLRF/…

标签: sql oracle plsql procedure


【解决方案1】:

感谢大家的支持

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

create TABLE FLAG 
( 
FLAG VARCHAR2(6) 
); 

INSERT INTO FLAG VALUES('PASS01');

【讨论】:

    【解决方案2】:
        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; 
    

    【讨论】:

      【解决方案3】:

      创建或替换过程 insert_sql

      x 整数;

      FLG FLAG.FLAG%type;

      开始

      dbms_output.enable;

      从 FLAG 中选择 FLAG 到 FLG;

      如果 FLG='PASS01' 那么

      DBMS_OUTPUT.PUT_LINE('PASS01');

      从 SOURCE_TEMP 中删除;

      DBMS_OUTPUT.PUT_LINE('SOURCE_TEMP-DELETED');

      INSERT INTO SOURCE_TEMP SELECT * FROM SOURCE;

      DBMS_OUTPUT.PUT_LINE('SOURCE_TEMP-INSERTED');

      更新标志集标志='PASS02';

      DBMS_OUTPUT.PUT_LINE('PASS02-updated');

      从 FLAG 中选择 FLAG 到 FLG;

      DBMS_OUTPUT.PUT_LINE('PASS02-SELECT');

      提交;

      如果结束;

      如果 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');

      更新标志集标志='PASS03';

      DBMS_OUTPUT.PUT_LINE('PASS03-updated');

      从 FLAG 中选择 FLAG 到 FLG;

      DBMS_OUTPUT.PUT_LINE('PASS03-FLG');

      提交;

      如果结束;

      --x :=1/0;

      如果 FLG='PASS03' 那么

      DBMS_OUTPUT.PUT_LINE('PASS03');

      从 NEWID_TEMP 中删除;

      DBMS_OUTPUT.PUT_LINE('NEWID_TEMP-DELETED');

      INSERT INTO NEWID_TEMP SELECT * FROM NEWID;

      DBMS_OUTPUT.PUT_LINE('NEWID_TEMP-INSERTEDD');

      更新标志集标志='PASS01';

      DBMS_OUTPUT.PUT_LINE('PASS01-updated');

      从 FLAG 中选择 FLAG 到 FLG;

      DBMS_OUTPUT.PUT_LINE('PASS01-FLG');

      提交;

      如果结束;

      当 NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('NO_DATA_FOUND!');

      WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('错误信息: !'|| SQLERRM ||' Sql Code: ' || SQLCODE);

      结束;

      【讨论】:

        【解决方案4】:
        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; 
        

        【讨论】:

        • 感谢 Prashant Mishra 感谢您的帮助,我创建了 Proc,您的程序很好,只是在发生某些错误时不满足,程序应该在错误行的下一条语句上运行
        猜你喜欢
        • 2012-09-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-19
        • 1970-01-01
        • 2015-10-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多