Sql 如何创建一个触发器,用于检查何时更新一个值,以确定定义的值是否仍然为null,如果没有,则更新一个表

Sql 如何创建一个触发器,用于检查何时更新一个值,以确定定义的值是否仍然为null,如果没有,则更新一个表,sql,oracle,plsql,oracle-sqldeveloper,database-trigger,Sql,Oracle,Plsql,Oracle Sqldeveloper,Database Trigger,如何创建由更新触发的触发器,然后检查更新的表中是否有某些值,以及另一个表是否仍然为空。如果不是,则应将第三个表中的值更改为sysdate 我的代码: CREATE OR REPLACE TRIGGER TRG_UPDATE_VALUE BEFORE UPDATE OF column1 ON table1 REFERENCING OLD AS OLD NEW AS NEW for each row DECLARE

如何创建由更新触发的触发器,然后检查更新的表中是否有某些值,以及另一个表是否仍然为空。如果不是,则应将第三个表中的值更改为sysdate

我的代码:

    CREATE OR REPLACE TRIGGER TRG_UPDATE_VALUE
        BEFORE UPDATE OF column1
        ON table1
    REFERENCING OLD AS OLD NEW AS NEW
        for each row
    DECLARE
        value_one_null int;
        value_two_null int;

    BEGIN
        SELECT COUNT(table1_id)
        INTO value_one_null
        FROM table1
        WHERE column1 IS NULL
        AND column2 = :NEW.column2;

        SELECT COUNT(table2_id)
        INTO value_two_null
        FROM table2
        WHERE column1 IS NULL
        AND column2 = :NEW.column2;

        IF (value_one_null = 0 AND value_two_null = 0)
            THEN
            UPDATE table3 SET table3.column1 = sysdate 
                WHERE table3_id = :NEW.column2;
        END IF;
    END;

编译触发器是有效的。但如果我试图更新表1,它会出错ORA-04091、ORA-06512、ORA-04088


我完全是PL/SQL的初学者,因此如果有人能帮助我修复此错误,那将是一件令人惊讶的事情。

主要问题是,您试图从目标表(触发器关联的表)读取行级触发器中的行。 RDMS禁止此操作

实现该功能的一般方法是通过复合触发器或包使用公共内存,并通过若干步骤实现该目标

请阅读Tom Kyte关于变异表和触发器的初始主题,以了解该主题

以下是数百种解释之一:


@Viorel谢谢你的回答。我不能更新表,但如果我将提交放在end if之后,则当值应设置为sysdate时会发生死锁。如果我不把它放在那里,它的值就不会改变。。。您知道如何解决这个问题吗?示例数据和期望的结果将帮助我了解您正在尝试做什么。您可能需要一种不同的方法来解决此问题,因为存在变异表问题。请不要使用PRAGMA autonomy_事务。也就是说,在这种情况下,相同的pragma在这里创建不可跟踪的bug。自治事务必须发出提交或回滚。如果发生任何后续错误或回滚事务,则数据库将不同步。同样,如果回滚并提交事务,则数据库将再次失去同步。突变错误是实现/设计选择不当的症状,自治事务只会使其复杂化。是的,它执行了语句,但代价是数据不正确。