0

我觉得这是甲骨文不想让我做的那些“如果你小心你就可以做到”的场景之一。

我的问题是我有一个配置表,我想通过触发器启用继承。考虑一个具有 SUPERVISOR ID 列的 Employee 表,如果 ID 更改,则“继承”的 SUPERVISOR NAME 会自行填充。

我想做一个简单的自我查找,以在 INS/UPD 时从另一行捕获一个值。但甲骨文拒绝作为变异触发器错误。

我的代码本质上是:

TRIGGER UPD_CHILD_RECORD
BEFORE INSERT OR UPDATE
ON MYSCHEMA.FAKE_EMPLOYEE
FOR EACH ROW
WHEN (NEW.SUPERVISOR_ID IS NOT NULL)
BEGIN
IF INSERTING OR UPDATING
THEN
    :NEW.SUPERVISOR_NAME = (
        SELECT MAX(NAME)
        FROM MYSCHEMA.FAKE_EMPLOYEE
        WHERE EMPLOYEE_ID = :NEW.SUPERVISOR_ID
    );
END IF;
END UPD_CHILD_RECORD
;

谢谢。

4

1 回答 1

0

这是正常行为。Oracle 保护您免受可能访问已更新表的不一致数据的影响。

想象一下这个场景。
您提交两个更新语句并有一个从同一个表中进行选择的触发器。让我们假设第一个语句被成功应用并且数据被改变了。现在是第二个声明的时候了。您希望触发器中的 select 语句有什么输出?它应该返回第一次更新之前的数据,还是应该包含所做的更改?您可能认为 Oracle 应该返回新数据。但首先,Oracle 并不真正了解您的意图,其次,这意味着您的查询依赖于行顺序,这与关系代数相矛盾。

您的问题的解决方案非常简单。您根本不需要该SUPERVISOR_NAME列。要获取主管的姓名,只需将表与自身连接并获得所需的结果,例如:

select t1.ID, t1.SUPERVISOR_ID, t2.NAME from FAKE_EMPLOYEE t1
    left join FAKE_EMPLOYEE t2 on t1.SUPERVISOR_ID = t2.ID;
于 2020-03-12T21:11:33.753 回答