我有以下表格:
Professor
id_professor
name
number_courses_assigned
Course
id_course
name_course
id_professor
我希望有一个触发器,在我将相同名称的表中插入或删除课程后,表格中的字段number_courses_assigned会立即更新。到目前为止,我已经完成了以下工作:
create or replace trigger update_number_courses
after insert on course
declare
codP course.id_professor%type;
countC professor.number_courses_assigned%type;
begin
select course.id_professor into codP from course;
select professor.number_courses_assigned into countC from professor where id_professor=codP;
update professor set number_courses_assigned=countC+1 where id_professor=codP;
end;
我遇到的问题是,当我想在Course表中插入一行时,Oracle SQL Developer返回错误并且不允许插入新记录,我收到的消息是:
Row 5: ORA-01422: exact fetch returns more than requested number of rows
任何帮助?
答案 0 :(得分:1)
您的代码中存在错误 此选择返回多个记录
select course.id_professor into codP from course;
我建议您将触发器更改为row-level-trigger
并通过:new
有关触发器的更多信息,请参阅此处http://www.techonthenet.com/oracle/triggers/after_insert.php http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/create_trigger.htm
您的代码中的更改将是:
create or replace trigger update_number_courses
after insert on course
FOR EACH ROW
declare
begin
update professor
set number_courses_assigned=number_courses_assigned+1
where id_professor=:new.id_professor;
end;
答案 1 :(得分:0)
触发器中的这一行可能会导致您的错误:
select course.id_professor into codP from course;
由于没有where子句,因此它将从表中选择所有行。如果有多行(包括您要插入的新行),则会抛出错误。 SELECT .. INTO
必须返回一行。
更好的方法是将其设置为行级触发器(AFTER INSERT FOR EACH ROW
)在这种情况下,您刚刚插入的行中的值可以通过隐式触发器访问行变量:NEW
。所以你可以写一下:
codP := :new.id_professor;
(根本不需要将它分配给局部变量,但是如果你愿意的话,你可以做到这一点。)
关于触发器其余部分的另一个注意事项是,没有必要选择当前分配的课程数,然后使用更新中的选择值。你可以简单地写下这样的更新:
update professor set
number_courses_assigned=number_courses_assigned+1
where id_professor=codP;