【问题标题】:Oracle DB. Insert Trigger with Merge statament inside. Table is mutating甲骨文数据库。在内部插入带有 Merge 状态的触发器。表正在变异
【发布时间】:2020-03-31 16:40:42
【问题描述】:

我有两个后端系统(旧的和新的)共享一个 Oracle 数据库。

在旧系统中,为了保存客户数据,有两个表

customers_A

ID   NAME  ETC
1    PETE  ....

customers_B

ID NAME ETC
1  JOSH ...
2  ROSS ...

在新系统中,我创建了一个名为 All_Costumer 的新表,用于连接这些表。 这个新表分别包含类型 A 和 B 的客户 ID。

All_Customers

ID           ID_CUSTOMER_A    ID_CUSTOMER_B
A19E----D2B0     1                 null
A19E----D2B1    null                 1
A19E----D2B2    null                 2

因此,当新系统创建 A 类型的新客户时,数据将插入到 customer_AAll_Customers 表中,同时 B 类型的客户也将插入。 p>

目前,旧系统也在工作,当创建A类型的新客户时,数据仅插入customer_A表,但我也需要All_Customers中的数据。

为了解决这个问题,我创建了一个内部带有 MERGE INTO 语句的 TRIGGER,如果此表上不存在该行(当旧系统创建 A 类型的新客户时),则在 All_Customers 中插入一行

CREATE OR REPLACE TRIGGER customers_trg

AFTER INSERT
ON customer_A

FOR EACH ROW

DECLARE
variables that doesn't matters

BEGIN
    MERGE INTO all_customers
        USING (SELECT :new.id id FROM customer_A where id = :new.id) customer
        ON (all_customers.id_customer_a = customer.id)
    WHEN NOT MATCHED THEN
        INSERT (id, id_customer_a)
        VALUES (SYS_GUID(), :new.id, null);
    COMMIT;
END;

但是当我尝试从旧系统创建新客户时,我收到此错误:

ORA-04091: table **customer_A** is mutating, trigger/function may not see it

有办法解决这个问题吗? 我尝试在 DECLARE 部分添加PRAGMA AUTONOMOUS_TRANSACTION;,但没有成功。

注意:我不能修改旧系统

【问题讨论】:

    标签: oracle plsql database-trigger


    【解决方案1】:

    当前的问题是您在针对该表的触发器中查询table_a;但你不需要。您的合并查询

    SELECT :new.id id FROM customer_A where id = :new.id
    

    可以做到

    SELECT :new.id id FROM dual
    

    即子句变成:

    ...
            USING (SELECT :new.id id FROM dual) customer
            ON (all_customers.id_customer_a = customer.id)
    ...
    

    您也不能在触发器中提交 - 除非它是自主的,这是不应该的。您说您已经尝试过了,但是如果回滚插入,它会中断,因为合并的行仍然存在。所以希望这种提交只是尝试和拒绝这种方法的结果。

    但无论如何它都可以in this db<>fiddle

    如果您不添加 GUID,您可以通过视图获得相同的效果:

    create or replace view all_customers (id_customer_a, id_customer_b) as
    select id, null from customers_a
    union all
    select null, id from customers_b;
    

    db<>fiddle

    【讨论】:

      猜你喜欢
      • 2016-06-11
      • 1970-01-01
      • 1970-01-01
      • 2016-06-17
      • 2011-05-06
      • 2020-12-22
      • 2018-08-20
      • 2015-02-04
      • 1970-01-01
      相关资源
      最近更新 更多