2016-11-05 22 views
2

テーブルのデータの変更の記録を保持しようとしています。私はこれを行うさまざまな方法がありますが、より便利に聞こえるが、私の状況で私はトリガを使用してこの機能を実装したいと思います。フィールドの更新でSQLがトリガーされ、別のテーブルに新しいレコードが挿入される

CREATE TABLE Applications 
(
    Application_ID INT NOT NULL, 
    Student_ID INT NOT NULL, 
    Job_ID INT NOT NULL, 
    ApplicationChange_TYPE VARCHAR(64) NOT NULL, 

    PRIMARY KEY (Application_ID), 
    FOREIGN KEY (Student_ID) REFERENCES Students(Student_ID), 
    FOREIGN KEY (Job_ID) REFERENCES Jobs(Job_ID), 

    CONSTRAINT CK_TYPE CHECK (ApplicationChange_TYPE in ('Submitted', 'Withdrawn', 'Invited For Interview', 'Invited to Assessment Centre', 'Rejected', 'Accepted')) 
); 

そして:私は2つのテーブル持って

CREATE TABLE ApplicationChanges 
(
    ApplicationChange_ID INT NOT NULL, 
    Application_ID INT NOT NULL, 
    ApplicationChange_TYPE VARCHAR(64), 
    ApplicationChange_DATETIME DATE NOT NULL, 

    PRIMARY KEY (ApplicationChange_ID), 
    FOREIGN KEY (Application_ID) REFERENCES Applications(Application_ID), 

    CONSTRAINT CK_APPTYPE CHECK (ApplicationChange_TYPE in ('Submitted', 'Withdrawn', 'Invited For Interview', 'Invited to Assessment Centre', 'Rejected', 'Accepted')) 
); 

私はアプリケーションのテーブル内のレコードのApplicationChange_TYPEフィールドが更新/編集時れるようにトリガを作成したいと思いますが、新しいレコードがありますApplicationChangesテーブルに作成されます。 Application_IDとApplicationChange_TYPEをApplicationテーブルの編集済みレコードからApplicationChanges内の新しいレコードに持ち越す必要があります。 ApplicationChange_DATETIMEフィールドには、現在の日付が入力されます。

は、現在では、両方のテーブルの主キーは、新規レコードの作成時に自動ID番号にシーケンスとトリガを使用しています。

入力があれば幸いです!そして私がすべて不明であったならば、謝罪します。

EDIT:

また、私はすでにこの時の試みを行っているが、私はそれのようにわからないことだし、それは私がそれを含めての任意のポイントがあったとは思いませんでしたように壊れているようです。しかし、ここにある:

CREATE OR REPLACE TRIGGER ApplicationsUpdateTrigger 
AFTER UPDATE ON Applications 
BEGIN 
    INSERT ApplicationChanges (Application_ID, ApplicationStatus_TYPE, ApplicationChange_TYPE) 
    SELECT Application_ID, ApplicationStatus_TYPE FROM Applications 
    JOIN inserted ON inserted.Application_ID = Applications.Application_ID 
    INSERT INTO ApplicationChanges (Application_ID, ApplicationStatus_TYPE, ApplicationChange_DATETIME) 
    VALUES (NULL, Application_ID, ApplicationStatus_TYPE, GETDATE()) 
END; 
/
+0

互換性のないデータベースタグを削除しました。実際に使用しているデータベースにタグを付けてください。 –

+0

なぜ「シーケンスと列のデフォルト」の代わりに「シーケンスとトリガ」ですか? –

+0

質問者がSQL Server/TSQLを使用しているので、これらのタグをロールバックしたという質問には何もありません。 –

答えて

0

(サンプル・トリガーでGETDATE()を使用してSQL Serverを示唆しているが)質問タグが言うように、私は、Oracleに固執するだろう。

ApplicationChangesテーブルに保存するApplicationChange_TYPE値は、変更前(古いもの)か変更後(新しいもの)のどちらであるか不明ですか?

は自動インクリメントID列の順序とトリガが正常に動作しますと仮定し、の両方のバリアントをカバーしてみましょう。

  1. 古い値:

    CREATE OR REPLACE TRIGGER ApplicationsUpdateTrigger 
    AFTER UPDATE ON Applications 
    FOR EACH ROW 
    BEGIN 
        IF (:OLD.ApplicationChange_TYPE IS NULL AND :NEW.ApplicationChange_TYPE IS NOT NULL) -- this one is actually redundunt as long as you've got NOT NULL constraint on Application.ApplicationChange_TYPE column 
        OR (:OLD.ApplicationChange_TYPE <> :NEW.ApplicationChange_TYPE) 
        THEN 
        INSERT INTO ApplicationChanges (Application_ID, ApplicationChange_TYPE, ApplicationChange_DATETIME) 
        VALUES (:OLD.Application_ID, :OLD.ApplicationChange_TYPE, sysdate); 
        END IF; 
    END; 
    /
    
  2. NEW VALUE:

    CREATE OR REPLACE TRIGGER ApplicationsUpdateTrigger 
    AFTER UPDATE OR INSERT ON Applications 
    FOR EACH ROW 
    BEGIN 
        IF (:OLD.ApplicationChange_TYPE IS NULL AND :NEW.ApplicationChange_TYPE IS NOT NULL) --this check is not redundant (:OLD.ApplicationChange_TYPE will be NULL on inserts) 
        OR (:OLD.ApplicationChange_TYPE <> :NEW.ApplicationChange_TYPE) 
        THEN 
        INSERT INTO ApplicationChanges (Application_ID, ApplicationChange_TYPE, ApplicationChange_DATETIME) 
        VALUES (:NEW.Application_ID, :NEW.ApplicationChange_TYPE, sysdate); 
        END IF; 
    END; 
    /
    

差はかなり化粧品である:第二の変異体は、UPDATE、INSERTとの両方で動作し、使用しています。新しいレコード値ではなく、古いレコード値。

関連する問題