2012-05-08 56 views
0

我有以下表格:Oracle触发器错误ORA-01427:错误ORA-04091

师资队伍表

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'

+0

这功课吗? –

+0

这是我用触发器练习的一些练习。你能帮忙吗? – user1382242

回答

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 ... VALUES或使用自治事务的触发器的行级插入触发器之外,这两者在此均不适用) 。所以如果你真的想用触发器做到这一点,你需要创建一个包含course_id值集合的包,一个用于初始化集合的before语句触发器,一个将:new.course_id添加到集合的行级触发器,以及遍历集合的after语句触发器并查找重复的值course_id。这是很多对象做的事情,不应该首先使用触发器完成,并且已经由您的约束完成。如果你刚刚了解触发器,我猜你还没有被教过关于软件包或集合的东西,这使得解决方案更加不合适。