创建一个处理两个表的触发器

时间:2014-11-24 15:23:32

标签: sql oracle oracle-sqldeveloper

我有两张桌子。表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

它被编译,但是当插入行时,它报告错误说触发器无效。我想知道是因为我在这里有行级或表级触发器,该怎么办?

2 个答案:

答案 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)。