1

注文テーブルが

  1. に挿入
  2. 更新しました

また、挿入/削除/更新は、金曜日の午後5時から月曜日の午前9時まで無効にされていました。次のソリューションはこれをすべてカバーしていますが、これは変更前のトリガーであるため、整合性制約をオフにする必要がありました(これはログテーブルにとって重要ですか?)

誰かが私がこれを行うことができ、整合性制約(logono列)を維持する方法について何か提案がありますか?

私は11Gのcompuntトリガーについて考えていましたが、以前の回答では、これは適切な使用法ではなく、下位互換性の問題もあると推測されていました。

   CREATE OR REPLACE TRIGGER log_order
BEFORE INSERT OR UPDATE OR DELETE ON orders
FOR EACH ROW
DECLARE out_of_hours EXCEPTION;
BEGIN
IF INSERTING THEN
IF
 TO_NUMBER( TO_CHAR( SYSDATE, 'DHH24' ) ) BETWEEN 109 AND 517 THEN 


    insert into order_log values
 (order_log_PK.nextval, 
 (select user from dual), 
 :NEW.ono, 
 (select  SYSDATE from dual), 
 'Order Inserted' ) ;
ELSE
    RAISE out_of_hours;
END IF;
END IF;
IF UPDATING THEN 
IF
 TO_NUMBER( TO_CHAR( SYSDATE, 'DHH24' ) ) BETWEEN 109 AND 517 THEN 


    insert into order_log values
 (order_log_PK.nextval, 
 (select user from dual), 
 :NEW.ono, 
 (select  SYSDATE from dual), 
 'order updated' ) ;
ELSE
    RAISE out_of_hours;
END IF;
END IF;
IF DELETING THEN
IF 
 TO_NUMBER( TO_CHAR( SYSDATE, 'DHH24' ) ) BETWEEN 109 AND 517
 THEN 
RAISE out_of_hourS;
END IF;
END IF;
EXCEPTION 
    WHEN out_of_hours THEN
    dbms_output.put_line('there is not privelages at this time');
    RAISE_APPLICATION_ERROR(-20001, 'CANNOT UPDATE OUT OF HOURS');
END;

ありがとう

編集

整合性の問題は、ログテーブルに入力される:NEW.ono値が、beforeトリガーであるために注文テーブルにまだ挿入されておらず、logono外部キーに違反しているために発生しました。

4

1 に答える 1

2

トリガーを単純化して、月曜日の午前9時から金曜日の午後5時の条件を1回だけチェックするようにして、ログテーブルに挿入する場所を1つだけにし、余分な例外と例外ハンドラーの必要性をなくすことができます。

トリガーをAFTERINSERTトリガーにして、データがすでに存在した後にトリガーを実行して、のキーを参照ORDERSする外部キー制約を作成できるようにすることができます。ただし、そのような制約を作成するのは非常に奇妙に思えます。ベーステーブルの子としてログテーブルを作成する場合、これは、常に子行が存在するため、から行を削除できないか、からすべての行を削除する必要があることを意味します。そのため、削除を行う前に。これらのどちらも一般的に特に望ましいものではありません。一般に、ログテーブルを持つことのポイントは、まだ存在するベーステーブルの行に対する操作だけでなく、すべての操作をログに記録することです。ORDER_LOGONOORDERSORDERSORDER_LOGONO

CREATE OR REPLACE TRIGGER log_order
  AFTER INSERT OR UPDATE OR DELETE ON orders
  FOR EACH ROW
DECLARE 
  l_operation varchar2(30);
BEGIN
  if to_number( to_char( sysdate, 'ddhh24' ) ) between 109 and 517
  then
    if inserting
    then
      l_operation := 'Order inserted';
    elsif updating
    then
      l_operation := 'Order updated';
    end if;

    -- Note that I'm guessing at the names of the columns in order_log
    insert into order_log( order_log_pk, 
                           modify_user,
                           ono,
                           modify_date,
                           description )
      values( order_log_PK.nextval,
              user,
              :new.ono,
              sysdate,
              l_operation );
  else 
    raise_application_error( -20001, 'Cannot update out of hours' );
  end if;
END;

INSERT挿入する列をリストせずにテーブルに挿入することは構文的に有効かもしれませんが、そうすることは危険です。将来、別の列を追加すると、必須ではない場合でも、INSERT失敗し始めます。列を明示的にリストすると、トリガーは引き続き機能します。また、列を明示的にリストしないと、データが間違った列に挿入されているバグを見つけるのは比較的困難です。列が何であるかを推測しました。適切な列名に置き換える必要があります。

于 2012-05-17T20:51:05.363 に答える