2016-11-05 87 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')) 
); 

和:

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從應用程序表中已編輯的記錄中繼承到ApplicationChanges中的新記錄中。 ApplicationChange_DATETIME字段應填入當前日期。

在當前,兩個表的主鍵都使用序列和觸發器來自動創建新記錄的ID號。

任何輸入將不勝感激!如果我一直不清楚,請致歉。

編輯:

此外,我已經作出了這個嘗試,但我是那麼不確定的,它看起來那麼壞,我不認爲有在包括它的任何一點。但在這裏,它是:

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)。

我不確定要在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. 新值:

    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及用途:新記錄值而不是:舊記錄值。

相關問題