所以我有两个相同的表,叫做SRC和EMP,我在emp表的ename字段上创建了一个唯一的索引。我想要做的是将员工从src表复制到emp表中,同时尊重员工姓名的唯一性条件。问题是它应该复制NIKON和两个CANON家伙中的一个......但它只复制NIKON。我被迫使用预先定义的例外,但我不知道该缺陷在哪里。我需要类似goto的东西,但有人建议使用异常。
Create Unique Index EIndex ON emp (ename)
Drop table SRC;
Create table SRC (EMPNO NUMBER(4) NOT NULL, ENAME CHAR(10), JOB CHAR(9), MGR NUMBER(4), COPIED NUMBER(1));
Insert into SRC (EMPNO, ENAME, JOB, MGR, COPIED) Values(9001,'NIKON','ANALYST',7902,null);
Insert into SRC (EMPNO, ENAME, JOB, MGR, COPIED) Values (9002,'FORD','ANALYST',7902,null);
Insert into SRC (EMPNO, ENAME, JOB, MGR, COPIED) Values (9003,'CANON','ANALYST',7902,null);
Insert into SRC (EMPNO, ENAME, JOB, MGR, COPIED) Values (9004,'CANON','ANALYST',7902,null);
DECLARE
Cursor copy_emp_cursor IS
Select empno, ename, job, mgr from SRC;
v_record copy_emp_cursor%ROWTYPE;
BEGIN
OPEN copy_emp_cursor;
LOOP
Fetch copy_emp_cursor INTO v_record;
EXIT WHEN copy_emp_cursor%NOTFOUND;
Savepoint do_insert;
INSERT INTO emp (empno, ename, job, mgr) values(v_record.empno, v_record.ename, v_record.job, v_record.mgr);
UPDATE SRC set COPIED = 1 where empno=v_record.empno;
END LOOP;
CLOSE copy_emp_cursor;
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
ROLLBACK TO do_insert;
UPDATE SRC set copied = 0 where ename=v_record.ename;
END;
答案 0 :(得分:1)
您应该在循环内处理DUP_VAL_ON_INDEX异常,以便循环可以继续使用下一条记录。我还建议您使用游标FOR-loop而不是显式游标 - 它会缩短代码并允许PL / SQL执行某些优化,如果您使用显式游标则无法执行这些优化:
BEGIN
FOR v_record IN (Select empno, ename, job, mgr from SRC)
LOOP
BEGIN
INSERT INTO emp (empno, ename, job, mgr)
values(v_record.empno, v_record.ename, v_record.job, v_record.mgr);
UPDATE SRC set COPIED = 1 where empno=v_record.empno;
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
UPDATE SRC set copied = 0 where ename=v_record.ename;
END;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Exception: ' || SQLCODE || ' - ' || SQLERRM);
ROLLBACK;
END;
分享并享受。