ORACLE变异触发错误[重复]

Posted

技术标签:

【中文标题】ORACLE变异触发错误[重复]【英文标题】:ORACLE Mutating trigger error [duplicate] 【发布时间】:2012-08-23 10:36:21 【问题描述】:

可能重复:ORACLE After update trigger: solving ORA-04091 mutating table error

所以我有一个触发器来检查管理员是否已被锁定无法登录(如果是,他们会将 1 设置为 temp_pw。然后它会向管理员发送一个四位数的密码来解锁他们的帐户。问题是我更新了 failed_logins 字段,在调用触发器之前,每次登录失败时将其递增 1。

触发器的其余部分会在向管理员发送带有密码的电子邮件之前检查是否有管理员的帐户被锁定。

如果我取出 Update Pi_admin_table set blah blah,它会发送电子邮件,但如果我包含它以在表中插入新密码,则会出现以下错误:

 Message: 60 ORA-00060: deadlock detected while waiting for resource
 ORA-06512: at "PI_USER_ADMIN.TR_ADMIN_LOCKOUT", line 17
 ORA-04088: error during execution of trigger
 'PI_USER_ADMIN.TR_ADMIN_LOCKOUT' UPDATE *pi_admin_table SET
 failed_logins = failed_logins + 1 where
 EMAIL='nathan@perceptive.co.uk' returning failed_logins into :bind_var

这是我的触发器:

create or replace
TRIGGER "TR_ADMIN_LOCKOUT" 
AFTER UPDATE ON PI_ADMIN_TABLE
for each row
declare
-- pragma autonomous_transaction seems to fix trigger mutation errors. 
-- Look at rewriting trigger later.
--pragma autonomous_transaction;
tempEmail varchar2(80 BYTE);
tempID varchar2(80 BYTE);
mail_host varchar2(255);
mail_port varchar2(255);
mail_from varchar2(255);
tempPW int;
begin
  SELECT EMAIL, ADMINID
    into tempEmail, tempID
    from pi_admin_table
    where TEMP_PW = :NEW.TEMP_PW;

  SELECT MAIL_HOST, MAIL_PORT, MAIL_FROM
    into mail_host, mail_port, mail_from
    from pi_settings_table;

  select dbms_random.value(1,10000)
    into tempPW
    from dual;

  if tempEmail IS NOT NULL then
    UPDATE PI_ADMIN_TABLE SET RESET_PW=round(tempPW) where adminid=tempID;
    send_mail(tempEmail,
              mail_host,
              mail_port,
              mail_from,
              'Locked Out Event',
              'Your administrator account was locked out. '|| chr(10) || chr(10) ||
              'Please use this four digit pass code next time try to log in' ||
              chr(10) || chr(10) ||  
              'Temp pass code: '|| round(tempPW) );
  end if;
END;

【问题讨论】:

简单地说,您的问题是因为您无法在触发器中更新要触发的表... 【参考方案1】:

Oracle 不允许 ROW 触发器中的代码对定义触发器的表发出 SELECT、INSERT、UPDATE 或 DELETE。您的选择是使用 AUTONOMOUS TRANSACTION(但请参阅 the post referenced in @Ben's comment above 的警告)或使用 COMPOUND TRIGGER。

分享和享受。

【讨论】:

【参考方案2】:

我建议您不要为该任务使用触发器。将你想要实现的逻辑封装在存储过程中。

【讨论】:

+1 - 好点。不应在触发器中执行此类业务逻辑。将此逻辑封装在 PL/SQL 过程或函数中并在适当的位置调用它会是更好的选择。

以上是关于ORACLE变异触发错误[重复]的主要内容,如果未能解决你的问题,请参考以下文章

错误触发器:表正在变异,触发器/函数可能看不到它

变异,触发器/函数在使用触发器时可能看不到错误

触发器上的变异错误以计算平均成本

SQL 表正在变异...错误

表正在变异,触发器可能看不到它

插入上的 Oracle 变异触发器