我有以下表格:
FACULTY表
CREATE TABLE "FACULTY"
( "FACULTY_ID" NUMBER(3,0),
"FACULTY_NAME" VARCHAR2(30),
"FACULTY_DEAN" VARCHAR2(30),
CONSTRAINT "FACULTY_PK" PRIMARY KEY ("FACULTY_ID") ENABLE
)
课程表
CREATE TABLE "COURSE"
( "COURSE_ID" NUMBER(5,0),
"COURSE_NAME" VARCHAR2(50),
"COURSE_LEVEL" NUMBER,
"FACULTY" NUMBER,
CONSTRAINT "COURSE_PK" PRIMARY KEY ("COURSE_ID") ENABLE
)
所以现在我想实现两件事
(1)在教师桌上更新faculty_id时。触发器将触发并使用新的faculty_id更新课程表中的相应行。它还将存储旧的faculty_id值,课程名称以及在course_log表中执行操作的日期。
以下是我的内容
create or replace trigger update_faculty
after update on faculty
for each row
begin
insert into course_log
values (:old.faculty_id,
(select course_name
from course
where faculty=:old.faculty_id),
sysdate);
update course
set faculty=:new.faculty_id
where faculty=:old.faculty_id;
end;
但是我收到以下错误。
错误ORA-01427:单行子查询返回多行ORA-06512:在“SYSTEM.UPDATE_FACULTY”,第2行ORA-04088:执行触发器'SYSTEM.UPDATE_FACULTY'时出错
关于如何解决它的任何想法?
(2)编写一个触发器,当尝试更改课程表中的course_id属性时触发,该触发器将检查课程表中是否已存在该值,并且如果它是新值则将成功更新。如果该值已存在于任何行中,则触发器将抛出一个应用程序错误,指出“该course_id已存在!更新未成功。”
下面是我的查询
CREATE OR REPLACE TRIGGER "UPDATE_COURSE_ID"
after update on course
for each row
declare
error number;
begin
select count(*)
into error
from course
where course_id=:new.course_id;
if error > 0 then
raise_application_error (-20000,'The course_id already found! Update not success');
end if;
if error = 0 then
update course set course_id=:new.course_id where course_id=:old.course_id;
end if;
end;
但是我收到了这个错误
错误ORA-04091:表SYSTEM.COURSE正在变异,触发器/函数可能看不到它ORA-06512:在“SYSTEM.UPDATE_COURSE_ID”,第5行ORA-04088:执行触发器'SYSTEM.UPDATE_COURSE_ID'时出错< / p>
答案 0 :(得分:0)
对于第一个问题,既然您可能希望在course_log
表中插入多行,则需要执行类似
create or replace trigger update_faculty
after update on faculty
for each row
begin
-- I'm guessing about the definition of the course_log table
insert into course_log( faculty_id, course_name, log_date )
select :old.faculty_id, course_name, sysdate
from course
where faculty=:old.faculty_id;
update course
set faculty=:new.faculty_id
where faculty=:old.faculty_id;
end;
对于第二个问题,使用触发器没有意义。你想要使用约束。并且course_id
course
已经存在主键约束,这已经阻止了重复的course_id
值。
用触发器执行此类操作是一个非常糟糕的主意。由于course
上的行级触发器无法查询course
表(如果您的insert语句始终为单行形式INSERT ... VALUES
或触发器,则行级插入触发器除外使用自治交易,这两者都不合适。因此,如果您真的想用触发器执行此操作,则需要创建一个包含course_id
值集合的包,一个初始化集合的before语句触发器,一个添加{{{ 1}}到集合,以及一个after语句触发器,它迭代集合并查找重复的:new.course_id
值。这是很多对象要做的事情,首先不应该使用触发器,而且已经由约束完成了。如果你刚刚学习了触发器,我猜你还没有被教过关于包或集合的知识,这使得解决方案更不合适。