我有一个程序procedure1
,如下所示,
表TESTTABLE123的值是,
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.
但是为什么连第一行都没有插入到第二个表中。
我的要求是如果发生错误,它应该继续迭代并插入即将到来的行。
答案 0 :(得分: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
替换为相应的唯一列名称。
答案 1 :(得分:1)
您可以使用RECORD
变量中的RECORD
(隐式创建SELECT / CURSOR)将其作为FOR LOOP
本身插入。< / p>
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;
答案 2 :(得分:0)
可以使用提示而不是异常处理:
INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(TESTTABLE124 , TESTTABLE124_PK) */
INTO TESTTABLE124 ...