`

触发器中SQL语句不能

SQL 
阅读更多
触发器中SQL语句不能:读取或更新触发语句的任何变异表也包括触发表本身,读取或更新该触发表的约束表的主键列、唯一性键列或外键列但是如果需要也可以更新其他列。这些限制约束适用于所有行级触发器。但有个特例就是如果INSERT只影响一行记录那么定义在这行上的行级BEFORE和AFTER触发器就不会将这个触发表当作变异表。
那么要想实现就意味这不能在行级触发器里查询该表,但是可以在语句级触发器里查询它。但是不能简单的将它设计成一个语句级触发器因为我们需要在触发器主体中使用:new.major的值。这个问题的解决办法就是创建2个触发器一个行级的一个语句的,在行级里记录:new.major的值但是不查询表,查询在语句里实现。那么怎么记录值呢,就要通过一个包了。
确保变量成为全局变量的唯一方法就是将它存放在某个包中:
create or replace package studentdata as
type t_majors is table of students.major%type index by binary_integer;
type t_ids is table of students.id%type index by binary
v_studentmajors t_majors;
v_studentids t_ids;
v_numbertries binary_integer:=0;
end studentsdata;

create or replace trigger rlimitmajors
before insert or update of major on students
for each row
begin
studentdata.v_numbertries:=studentdata.v_numbertries+1;
studentdata.v_studentmajors(studentdata.v_numberies):=:new.major;
studentdata.v_studentids(studentdata.v_numberies):=:new.id;
end rlimitmajors;

create or replace trigger slimitmajors
after insert or update of major on students
declare
v_maxstudents constant number:=2;
v_currentstudents number;
v_studentid student.id%type;
v_major students.major%type;
begin
for v_loopindex in 1..studentdata.v_numberies loop
v_studentid:=studentdata.v_studentids(v_loopindex);
v_major:=studentdata.v_studentmajors(v_loopindex);
select count(*) into v_currentstudents from students where major=v_major;
if v_currentstudents>v_maxstudents then
raise_application_error(-20000,'too many students for major '||v_major||'because of student'||v_studentid);
end if;
studentdata.v_numberies:=0;
end slimitmajors;

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics