【问题标题】:Trigger Compiles Fine But Encounters ORA-04091 on UPDATE触发器编译正常但在更新时遇到 ORA-04091
【发布时间】:2017-09-18 23:39:56
【问题描述】:

1.) 我为名为@9​​87654321@ 的表编写了一个触发器,如下所示:

CREATE OR REPLACE TRIGGER grades_before_update
BEFORE UPDATE OF grade_percent
ON grades
FOR EACH ROW
DECLARE
     grade_percent_var  NUMBER;
BEGIN
     SELECT  grade_percent
     INTO    grade_percent_var
     FROM    grades
     WHERE   student_id = :new.student_id;    

     IF (grade_percent_var > 100 OR grade_percent_var < 0) THEN
          RAISE_APPLICATION_ERROR(-20001, 'grade percent must be between 0 and 100');
     END IF;
END;
/

它编译得很好。我的 2 列 grades 表的示例如下:

student_id  grade_percent 
1           70
2           85 
3           90
4           70

当我尝试按如下方式测试此触发器时,问题就出现了:

UPDATE grades
SET grade_percent = 80
WHERE student_id = 1;

它给了我一个

错误 ORA-04091:表 GRADES 正在变异,触发器/函数可能不会 看见。重写触发器(或函数),使其不会读取 表。

2.) 另外,我计划在我的触发器中包含另一个 IF 语句,以检查输入的新 Grade_percent 是否介于 0 和 1 之间。如果是,那么它应该将该十进制值转换为整数例如百分比值:

UPDATE grades
SET grade_percent = 0.9
WHERE student_id = 2;

这是我目前所拥有的,我不确定如何编写代码的第二行:

 IF (grade_percent_var > 0 OR grade_percent_var < 1) THEN
      INSERT(grade_percent_var * 100);  

第二行应该将从 0-1 插入的任何值转换为整数百分比,例如:0.7 转换为 70% 并将其插入该行的列中。但是,这是一个语法错误,我不知道如何从这里开始。

非常感谢任何帮助。谢谢。

【问题讨论】:

  • 仅供参考,许多其他语言的许多代码都可以编译,但在运行时会出现错误,因此您问题的“编译正常但”部分并没有添加太多信息。例如“我的 Java 程序编译正常,但无法打开此文件...”

标签: sql oracle plsql triggers ora-04091


【解决方案1】:

首先,您不需要为此触发:

alter table grades add constraint chk_grades_grade_percent
    check (grade_percent between 0 and 100);

其次,您可以只使用触发器的新值——如果您必须使用触发器:

CREATE OR REPLACE TRIGGER grades_before_update
BEFORE UPDATE OF grade_percent
ON grades
FOR EACH ROW
BEGIN
     IF (:new.grade_percent > 100 OR :new.grade_percent < 0) THEN
          RAISE_APPLICATION_ERROR(-20001, 'grade percent must be between 0 and 100');
     END IF;
END;
/

【讨论】:

  • 有一个协议规定我不能自己更改表结构。
  • 我也收到了 PLS-0049:'new.grade_percent_var' 上的绑定变量错误。
  • @5120bee - 看起来 _var 只是偶然留下的,从您的局部变量名称转换为列名称。希望你已经明白了……
  • 是的,我想就是这样。此触发器也可以正常编译,但在使用简单的 UPDATE 查询对其进行测试时,它仍然存在 ORA-04091 表变异错误。
  • 为了便于阅读,我更喜欢if :new.grade_percent not between 0 and 100。一方面,它更接近错误消息。
猜你喜欢
  • 1970-01-01
  • 2011-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-30
  • 1970-01-01
  • 1970-01-01
  • 2013-05-13
相关资源
最近更新 更多