【问题标题】:trigger to update specific column when insert/update happened in same table当插入/更新发生在同一个表中时触发更新特定列
【发布时间】:2021-01-12 06:04:51
【问题描述】:

我尝试编写一个触发器,当用户在同一个表中插入或更新一行时,该触发器将更新一列。 例子: 插入用户(ID,F_NM,L_NM,EMAIL)值('1','John','Doe','john.doe@market.org.com'); 插入后,我想调用:update user set ORG = 'market' where ID = '1'。

create or replace trigger user_change
after insert or update of EMAIL on USER
for each row
declare
  NEW_ORG VARCHAR(10);
BEGIN
  CASE
    when :NEW.EMAIL like '$@market.org.com' then
      NEW_ORG := 'market';
    ........
  END CASE;

  UPDATE USER set ORG = NEW_ORG where ID = :NEW.ID
END;

正在计算新的 ORG 工作,但我无法让更新语句工作。 我得到'ORA-04091 table USER is mutating,trigger/function may not see it',这是由于我同时插入/更新同一条记录。尝试将“pragma automatic_transaction”和“commit”添加到触发器中,字段的插入/更新有效,但 ORG 没有得到更新。

还尝试更改为 INSTEAD OF INSERT OR UPDATE OF EMAIL 但我不断收到“ORA-04073 column list not valid for this trigger type”

create or replace trigger user_change
instead of insert or update of EMAIL on USER

虽然我得到“ORA-25002 无法在表上创建而不是触发器”

create or replace trigger user_change
instead of insert on USER

【问题讨论】:

  • 你的 oracle 版本是什么?

标签: sql oracle triggers sql-update sql-insert


【解决方案1】:

看起来您的org 列可以计算虚拟列。在这种情况下,最好创建用户定义的确定性 pl/sql 函数,该函数返回正确的计算值并将其添加到您的表中,例如:

Alter table t add org varchar2(30) generated always as (f_get_org(email))

【讨论】:

    【解决方案2】:

    当您可以在写入之前设置值时,为什么不简单地将触发器转换为 before 触发器?这样,您无需在表上运行新的 DML 语句,从而避免了“变异”错误。

    create or replace trigger user_change
    after insert or update of email on user
    for each row
    begin
        if :new.email like '%@market.org.com' then
            :new.org := 'market';
        end if;
    end;
    

    【讨论】:

    • @HangLin:触发器在插入或更新伪表:new 之前中设置org 的值。然后将修改后的值与其余数据一起插入或更新到表中。
    • 非常感谢,过去 3 个小时我一直在研究这个问题。不知道我可以修改触发器内的原始数据。
    猜你喜欢
    • 1970-01-01
    • 2018-01-12
    • 1970-01-01
    • 2020-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-18
    • 1970-01-01
    相关资源
    最近更新 更多