【发布时间】:2013-11-24 02:01:18
【问题描述】:
我有两个表 - XX 和 YY,它们的触发器在更新时相互调用。
XX 上的触发器是这样的:
CREATE OR REPLACE TRIGGER SCMA.XX_RBIU
BEFORE INSERT OR UPDATE
ON SCMA.XX FOR EACH ROW
-- PL/SQL BLOCK
BEGIN
IF UPDATING THEN
-- Only update the YY row if the branch id has
-- been modified on the XX row
IF :NEW.BRANCH_ID <> :OLD.BRANCH_ID THEN
UPDATE YY TP
SET TP.BRANCH_ID = :NEW.BRANCH_ID
WHERE TP.XX_ID = :NEW.XX_ID;
END IF;
END IF;
...
... -- Other PL/SQL statements that do some necessary
... -- computation and do not use any SQL.
...
END;
/
YY上的触发器是这样的:
CREATE OR REPLACE TRIGGER SCMA.YY_RBIU
BEFORE INSERT OR UPDATE
ON SCMA.YY
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
DECLARE
v_xx_type xx.xx_type_code%TYPE;
BEGIN
select x.xx_type_code
into v_xx_type
from XX x
where x.xx_id = :new.xx_id;
...
... -- Other PL/SQL statements that do some necessary
... -- computation and do not use any SQL.
...
END;
/
我知道触发器YY_RBIU 中的SELECT 语句给出了这个错误。如何对触发器进行编码以避免它?
我试图将YY_RBIU 中的SELECT 语句包装在IF INSERTING THEN 块内,但这不适用于任何更新。如果从触发器XX_RBIU 调用更新,如何跳过此SELECT 语句?
我也尝试将PRAGMA AUTONOMOUS_TRANSACTION 放入XX_RBIU,但这会导致死锁。
我也尝试参考this、this、this 和this,但找不到解决方案。
非常感谢任何帮助。
【问题讨论】:
-
为什么你有一个看似非规范化的数据模型,其中
xx和yy都有xx_id和branch_id列?您是否有可能修复数据模型,以便您不会将此映射存储在两个不同的地方?如果没有,为什么需要这种数据模型? -
@JustinCave- 这是业务需求。在某些情况下
yy.branch_id可能与xx.branch_id不同,因此我们必须在两个不同的表中维护它们。然而,业务还要求如果xx.branch_id更新,那么yy.branch_id中也应反映相同的内容。yy.branch_id稍后可能会更改。 -
在我看来,这对于触发器来说太复杂了。这是应该成为应用程序代码一部分的业务逻辑。
标签: oracle plsql triggers oracle11gr2 mutating-table