0

私は次のテーブルを持っています:

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
   )

だから今私は2つのことを達成したい

(1)faculty_idがfacultyテーブルで更新されたとき。トリガーが起動し、コーステーブルの対応する行が新しい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」の実行中にエラーが発生しました

4

1 に答える 1

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;

2番目の質問では、トリガーを使用することは意味がありません。制約を使用する必要があります。そして、あなたはすでに主キーの制約がありcourse_idcourseそれはすでに重複course_id値を防いでいます。

この種のことをトリガーで強制することは、本当に悪い考えです。行レベルのトリガーcourseはテーブルをクエリできないためcourse(挿入ステートメントが常に単一行形式である場合の行レベルの挿入トリガー、INSERT ... VALUESまたは自律トランザクションを使用するトリガーを除き、どちらもここでは適切ではありません)。したがって、トリガーを使用してこれを本当に実行したい場合は、course_id値のコレクション、コレクションを初期化するbeforeステートメントトリガー、コレクションに追加する行レベルのトリガー:new.course_id、およびafterを含むパッケージを作成する必要があります。コレクションを反復処理して重複を探すステートメントトリガーcourse_id値。それは、そもそもトリガーで実行されるべきではないことを実行するための多くのオブジェクトであり、それはすでに制約によって実行されています。トリガーについて学習しているだけの場合は、パッケージやコレクションについてまだ教えられていないため、ソリューションの適切性がさらに低くなっていると思います。

于 2012-05-08T14:57:14.560 に答える