在oracle中的2个表之间的FK约束上更新或删除后触发

时间:2015-01-16 11:40:44

标签: oracle plsql triggers

我有以下表格:

create table emp_test_lucian as select employee_id,last_name,first_name,department_id from employees;
ALTER TABLE emp_test_lucian
ADD PRIMARY KEY (employee_id);

create table dept_test_lucian as select department_id,department_name from departments_copy;
ALTER TABLE dept_test_lucian
ADD PRIMARY KEY (department_id);

在这个表上,我想执行不同的操作,例如:如果部门被删除(来自dept_test_lucian),我将删除emp_test_lucian中具有触发器的那个部门ID的所有行。当使用以下代码声明2之间没有fk时,这很好用:

CREATE OR REPLACE TRIGGER triger5
 BEFORE UPDATE or DELETE on dept_test_lucian
FOR EACH ROW
BEGIN
 IF DELETING then
  delete 
  from emp_test_lucian
  where department_id = :OLD.department_id;
 else if UPDATING('department_id') then
  UPDATE emp_test_lucian
  set department_id = :NEW.department_id
  where department_id = :OLD.department_id;
 END IF;
END IF;
END;
/

即使我在2个表之间有fk,我还可以添加到上面的代码中工作:

ALTER TABLE emp_test_lucian
  ADD CONSTRAINT fk_dep_id FOREIGN KEY(department_id) REFERENCES dept_test_lucian(department_id);

the current code returns :
Error report:
ORA-00001: unique constraint (C##LABORATOR.SYS_C009994) violated
ORA-06512: at line 2
00001. 00000 -  "unique constraint (%s.%s) violated"
*Cause:    An UPDATE or INSERT statement attempted to insert a duplicate key.
           For Trusted Oracle configured in DBMS MAC mode, you may see
           this message if a duplicate entry exists at a different level.
*Action:   Either remove the unique restriction or do not insert the key.

1 个答案:

答案 0 :(得分:1)

您需要明确哪个表是“父”,哪个表是“子”。

在你的例子中:
- 家长:dept_test_lucian
- 孩子:emp_test_lucian

让我们调用'dept_test_lucian':表A
让我们调用'emp_test_lucian':TableB

我得出这个结论,因为TableB.department_id上有一个CONSTRAINT“只能存在一个值 在“TableA.department_id”

中 该错误消息告诉您“主键被通过”。 您表上的主键是:
- “TableA.employee_id”
- “TableB.department_id”

显然,您正试图在其中一个已存在该值的列中插入值。 如果“TableA.employee_id”中已存在“1”,则会出现此类错误。

我在你的触发器中看到的是:
你有一个BEFORE UPDATE触发器。

因此,Trigger会查看“TableA”(父级)上是否有UPDATE。
然后你首先尝试UPDATE“TableB”(孩子)。
这可能很棘手,因为“TableB.department_id”只能包含“TableA.department_id”中存在的值。
如果“TableA.department_id”中不存在新的UPDATE值,则无法在“TableB.department_id”中更新该值