这是我上一篇文章中的后续问题: PL/SQL Triggers with aggregate function
我有一个名为updategpa
的触发器,只要在student
表中更改成绩,就会更新course
表中的gpa。
此触发器由于“更新了”而被调用'当course
表收到新数据时,触发器更新assignments
表。
问题:在调用触发器之前和之后gpa是0
?
有谁可以说我的触发器出了什么问题?
drop table courses;
drop table student;
drop table assignments;
create table student (sid integer, sname char(10), saddress char(10), gpa integer);
create table courses (sid integer, cid integer, cgrade integer);
create table assignments ( sid integer, cid integer, aid integer, agrade integer);
insert into student (sid, sname, saddress, gpa) values (1, 'Mike', 'Brighton', 0);
insert into courses (sid, cid, cgrade) values(1, 2000, 0);
insert into assignments values(1, 2000, 1, 70);
insert into assignments values(1, 2000, 2, 80);
create or replace trigger updateGrades before insert or update or delete of agrade on assignments for each row
begin
if inserting then
update courses set cgrade = :new.agrade where cid = :new.cid and sid = :new.sid;
elsif updating then
update courses set cgrade = :old.agrade + (:new.agrade - :old.agrade)
where cid = :new.cid and sid = :new.sid;
elsif deleting then
delete from courses where cid = :new.cid and sid = :new.sid;
end if;
end;
/
show errors;
create or replace trigger updategpa after insert or update or delete of cgrade on courses for each row
begin
if inserting then
update student set gpa =
(select avg(cgrade) from courses inner join student on courses.sid = student.sid
)
where sid = 1;
elsif inserting then
update student set gpa =
(select avg(cgrade) from courses inner join student on courses.sid = student.sid
)
where sid = 1;
elsif deleting then
delete from student where sid = :new.sid;
end if;
end;
/
show errors;
select * from courses;
select * from student;
select * from assignments;
update assignments set agrade = agrade + 5;
select * from courses;
select * from student;
select * from assignments;
控制台输出:
SQL> select * from student;
SID SNAME SADDRESS GPA
---------- ---------- ---------- ----------
1 Mike Brighton 0
SQL> select * from assignments;
SID CID AID AGRADE
---------- ---------- ---------- ----------
1 2000 1 70
1 2000 2 80
SQL>
SQL> update assignments set agrade = agrade + 5;
2 rows updated.
SQL>
SQL> select * from courses;
SID CID CGRADE
---------- ---------- ----------
1 2000 85
SQL> select * from student;
SID SNAME SADDRESS GPA
---------- ---------- ---------- ----------
1 Mike Brighton 0
SQL> select * from assignments;
SID CID AID AGRADE
---------- ---------- ---------- ----------
1 2000 1 75
1 2000 2 85
答案 0 :(得分:0)
问题的根源是您的updategpa
触发器需要跟踪行级别对COURSES的每次更改,然后汇总这些更改以维护每个学生的运行总计。这是复合触发器的一个很好的用例。 Find out more。
create or replace trigger updategpa
for update or update or insert on courses compound trigger
type cid_nt is table of courses%rowtype;
upd_recs cid_nt;
before statement is
begin
upd_recs := cid_nt();
end before statement;
before each row is
begin
upd_recs.extend();
if inserting or updating then
upd_recs(upd_recs.count()).sid := :new.sid;
else
upd_recs(upd_recs.count()).sid := :old.sid;
end if;
end before each row;
after each row is
begin
null;
end after each row;
after statement is
begin
for idx in 1 .. upd_recs.count() loop
update student
set gpa = (select avg(cgrade)
from courses
where courses.sid = student.sid )
where sid = upd_recs(idx).sid;
end loop;
end after statement;
end;
以下是a LiveSQL demo(需要免费的OTN帐户)。