如何将以下简单触发器转换为复合触发器,以避免ORA-04091 table is mutating error
?
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;
/
我问的原因是因为我每次使用UPDATE
查询测试此触发器时都会这样:
UPDATE grades
SET grade_percent = 90
WHERE student_id = 1;
我得到ORA-04091 table is mutating error
。我已经搜索过了,这个网站说我需要一个复合触发器来避免这个错误:
但我不知道如何开始。
答案 0 :(得分:2)
您不需要复合触发器,只需要检查当前值即可。该错误是因为您正在选择要更新的表,这是一个无效的操作(对于之前的触发器)。
所以你只需要像对<Window x:Class="WpfApp15.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp15"
xmlns:controls="clr-namespace:WpfControlLibrary1;assembly=WpfControlLibrary1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid Background="Green">
<controls:PanelChoice />
</Grid>
</Window>
一样访问该字段的值
这将是:
:new.student_id
无需声明任何变量或select语句。 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;
是:NEW.grade_percent
命令中使用的值。