2014-11-24 69 views
1

我有两个表。表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 

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

回答

1

检查警告你的编译后触发,它会给你一个确切的原因,它不能被编译。但是,当您修复编译错误[s]时,在插入到B期间,您将遇到 “ORA-04091:表XXXX正在变异...”:您无法在行级触发器内发出对目标表的查询,除非它使用自主交易。

常见的解决方法包括创建3个触发器,2个语句级别--BEFORE和AFTER操作,以及一个行级别(有不少文章描述此方法,例如https://asktom.oracle.com/pls/asktom/ASKTOM.download_file?p_file=6551198119097816936)。

+0

谢谢,修正了,但还是想着如何解决它,也许把它分成两个触发器。 – 2014-11-24 15:44:40

+0

2触发器不会有帮助 - 您需要按照文章中的描述使用3。另一种选择是创建存储过程,将数据插入'B'并打印所需的信息。然后,您可以撤销除存储过程之外的任何人的插入权限。注意:你的4个选项可以用一个替换。 – a1ex07 2014-11-24 15:58:05

1

你忘了最后的END;只是错字,但在其他情况下:

错误:PLS-00405:子查询不允许在此上下文中 当您使用IN运算符调用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; 
+0

谢谢,修正了,但还是想着如何解决它,也许把它分成两个触发器。 – 2014-11-24 15:44:14