2014-03-07 26 views
1

我有一個過程procedure1給出如下,在執行這個程序,我得到的錯誤繼續迭代時DUP_VAL_ON_INDEX

值表TESTTABLE123是,

enter image description here

create or replace procedure procedure1 as 
CURSOR TESTTABLE124_CUR IS SELECT * FROM TESTTABLE123 ; 
begin 

    FOR i IN TESTTABLE124_CUR LOOP 
     BEGIN 
     INSERT INTO TESTTABLE124 (select * from TESTTABLE123); 

     EXCEPTION 
     WHEN DUP_VAL_ON_INDEX THEN 
     DBMS_OUTPUT.PUT_LINE('duplicate value'); 
     CONTINUE; 
     END ; 
     END LOOP; 
     commit; 
end procedure1; 

An UPDATE or INSERT statement attempted to insert a duplicate key.

  1. 但是爲什麼即使第一行沒有插入到第二個表中。

  2. 我的要求是如果發生錯誤,它應該繼續迭代並插入即將到來的行。

回答

3

的問題是,您要插入所有行在每個迭代。在你的情況下,你只想在循環(逐行處理)內插入一個行,這樣如果失敗只有一行失敗並且可以插入下一行。

CREATE OR REPLACE PROCEDURE procedure1 AS 
    CURSOR TESTTABLE124_CUR IS 
     SELECT * FROM TESTTABLE123; 
BEGIN 
    FOR i IN TESTTABLE124_CUR LOOP 
     BEGIN 
     INSERT INTO TESTTABLE124 VALUES (i.col1, i.col2...i.coln);  
     EXCEPTION 
     WHEN DUP_VAL_ON_INDEX THEN 
      DBMS_OUTPUT.PUT_LINE('duplicate value');   
     END; 
    END LOOP; 
    -- COMMIT; don't commit inside procedures 
END procedure1; 

或者,你只能插入不會引發異常的行(這將是更有效):

CREATE OR REPLACE PROCEDURE procedure1 AS 
BEGIN 
    INSERT INTO TESTTABLE124 
     (SELECT * 
     FROM TESTTABLE123 t_old 
     WHERE t_old.pk NOT IN (SELECT t_new.pk FROM TESTTABLE124 t_new)); 
    -- COMMIT; don't commit inside procedures 
END procedure1; 

更換pk用適當的唯一的列名。

+0

在我需要寫'i.col1,i.col2 ... i.col100'如果我有100第一部分列? – NaaN

+1

是的,一般來說,您必須在靜態SQL中編寫所有列名。但是,您可以使用行類型,請參見[Oracle:將rowtype數據插入到另一個表中](http://stackoverflow.com/a/13867022/119634)。 –

1

您可以在FOR LOOP變量使用RECORD創造了SELECT/CURSOR)將它作爲一個RECORD本身..!

create or replace procedure procedure1 as 
CURSOR TESTTABLE124_CUR IS SELECT * FROM TESTTABLE123 ; 
begin 

    FOR REC IN TESTTABLE124_CUR LOOP 
     BEGIN 
     INSERT INTO TESTTABLE124 
      VALUES REC ; 
     --- Just Specify the name.. But the column order should be same 
     EXCEPTION 
     WHEN DUP_VAL_ON_INDEX THEN 
      DBMS_OUTPUT.PUT_LINE('duplicate value'); 
      CONTINUE; 
     END ; 
     END LOOP; 
     commit; 
end procedure1; 
+0

如果沒有'CONTINUE'也同樣適用? – NaaN

+1

是的..你可以用'NULL;'替換'CONTINUE''只是_suppressing_異常 –

0

一個提示,可以用來代替異常處理:

INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(TESTTABLE124 , TESTTABLE124_PK) */ 
INTO TESTTABLE124 ... 
相關問題