我有两张桌子。表A就像
Name color
a1 red
a2 yellow
a3 black
a4 blue
表B就像
Name minutes action
b1 10 jump
b2 20 run
b3 40 dance
我正在创建一个在表B中插入行的触发器。如果该操作在B中存在,那么我打印新添加的信息。此外,如果新添加的人的颜色为红色,我将计算表B中有多少分钟的人数。代码就像
create or replace trigger TR_insert_count
Before INSERT On B
For each row
DECLARE
l_act integer;
l_less integer;
l_more integer;
l_equal integer;
Begin
select count(1) into l_act
From B
Where Action=:new.Action;
select count(*)
into l_less
From B
Where Action=:new.Action and MINUTES > :new.minutes;
select count(*)
into l_more
From B
Where Action=:new.Action and MINUTES < :new.minutes;
select count(*)
into l_equal
From B
Where Action=:new.Action and MINUTES = :new.minutes;
if(l_act>0) then
DBMS_OUTPUT.PUT_LINE ('There is duplicate.');
DBMS_OUTPUT.PUT_LINE ('The new input info is with name ' || :new.Name || ' with
activity ' || :new.action ||' for ' ||:new.minutes || ' minutes.');
if(:new.name in (select Name From A where color='red')) then
DBMS_OUTPUT.PUT_LINE('There are '||l_more ||'people having more minutes.');
DBMS_OUTPUT.PUT_LINE('There are '||l_less ||'people having less minutes.');
DBMS_OUTPUT.PUT_LINE('There are '||l_equal ||'people having the same minutes.');
end if;
end if;
end
它被编译,但是当插入行时,它报告错误说触发器无效。我想知道是因为我在这里有行级或表级触发器,该怎么办?
答案 0 :(得分:1)
错误:PLS-00405:此上下文中不允许使用子查询 用IN运算符调用IF时。
你必须改变你的if,就像这样:
select count(1) into l_count From A where color='red' and Name = :new.name;
if (l_count>0) THEN ....
DBMS_OUTPUT.PUT_LINE('There are '....
end if;
答案 1 :(得分:1)
在编译触发器后检查警告,它将为您提供无法编译的确切原因。
然而,当你修复编译错误[s]时,你会命中
&#34; ORA-04091:表格XXXX正在变异......&#34;插入B
期间:除非使用自治事务,否则不能在行级触发器内对目标表发出查询。
常见的解决方法包括创建3个触发器,2个语句级别 - BEFORE和AFTER操作,以及一个行级别(有很多文章描述了这种方法,例如https://asktom.oracle.com/pls/asktom/ASKTOM.download_file?p_file=6551198119097816936)。