用于跟踪更改历史记录的SQL触发器 - ORACLE DB

时间:2013-12-24 00:24:36

标签: sql oracle triggers

我有一个表cust_info,需要跟踪更新和删除。我创建了2个新表(archive_customers与cust_info相同,但customers_hist包含两个额外的实例(changed_by和change_date))。

    CREATE TABLE CUST_INFO
    (
     CUST_ID       NUMBER(15),
     CUST_F_NAME   VARCHAR(20),
     CUST_L_NAME   VARCHAR(20),
     CUST_ADDRESS  VARCHAR(40),
     CITY          VARCHAR(30),
     STATE         VARCHAR(30),
     ZIP           NUMBER,
     PHONE         VARCHAR(12),
     PRIMARY KEY (CUST_ID)
     );

我正在寻找类似的问题,这是我到目前为止所得到的:

    CREATE OR REPLACE TRIGGER TRIGGER_UPDATE
    BEFORE UPDATE ON CUST_INFO
    FOR EACH ROW
    BEGIN
    INSERT INTO CUSTOMERS_HIST
    (
     CUST_ID,
     CUST_F_NAME,
     CUST_L_NAME,
     CUST_ADDRESS,
     CITY,
     STATE,
     ZIP,
     PHONE,
     SYSDATE
     )
      SELECT 
      OLD.CUST_ID,
      OLD.CUST_F_NAME,
      OLD.CUST_L_NAME,
      OLD.CUST_ADDRESS,
      OLD.CITY,
      OLD.STATE,
      OLD.ZIP,
      OLD.PHONE
      FROM CUST_INFO 
      END;

      CREATE OR REPLACE TRIGGER TRIGGER_DELETE
      BEFORE DELETE ON CUST_INFO
      FOR EACH ROW
      BEGIN
      INSERT INTO ARCHIVE_CUSTOMERS
      (
      CUST_ID,
      CUST_F_NAME,
      CUST_L_NAME,
      CUST_ADDRESS,
      CITY,
      STATE,
      ZIP,
      PHONE
      )
      SELECT 
      OLD.CUST_ID,
      OLD.CUST_F_NAME,
      OLD.CUST_L_NAME,
      OLD.CUST_ADDRESS,
      OLD.CITY,
      OLD.STATE,
      OLD.ZIP,
      OLD.PHONE
      FROM CUST_INFO 
      END;

另外,我不知道如何填充change_by和change_date ??

如果您需要更多信息,请发表评论。

谢谢

1 个答案:

答案 0 :(得分:3)

也许您可以分别对usersysdate使用chnage_bychange_date内置函数。如果我想将更改历史存储在表中,我写的代码就完全不同了。然而,对于您的示例,代码如下:

CREATE OR REPLACE TRIGGER TRIGGER_UPDATE
    BEFORE UPDATE
    ON CUST_INFO
    FOR EACH ROW
BEGIN
    INSERT INTO CUSTOMERS_HIST (CUST_ID,
                                CUST_F_NAME,
                                CUST_L_NAME,
                                CUST_ADDRESS,
                                CITY,
                                STATE,
                                ZIP,
                                PHONE,
                                SYSDATE,
                                change_by,
                                change_date)
        SELECT OLD.CUST_ID,
               OLD.CUST_F_NAME,
               OLD.CUST_L_NAME,
               OLD.CUST_ADDRESS,
               OLD.CITY,
               OLD.STATE,
               OLD.ZIP,
               OLD.PHONE,
               user,
               sysdate
          FROM CUST_INFO;
END;
/

CREATE OR REPLACE TRIGGER TRIGGER_DELETE
    BEFORE DELETE
    ON CUST_INFO
    FOR EACH ROW
BEGIN
    INSERT INTO ARCHIVE_CUSTOMERS (CUST_ID,
                                   CUST_F_NAME,
                                   CUST_L_NAME,
                                   CUST_ADDRESS,
                                   CITY,
                                   STATE,
                                   ZIP,
                                   PHONE,
                                   change_by,
                                   change_date)
        SELECT OLD.CUST_ID,
               OLD.CUST_F_NAME,
               OLD.CUST_L_NAME,
               OLD.CUST_ADDRESS,
               OLD.CITY,
               OLD.STATE,
               OLD.ZIP,
               OLD.PHONE,
               user,
               sysdate
          FROM CUST_INFO;
END;
/

这就是你问题的答案。

现在,如果我是你,我会按如下方式构建一个审计表:

TABLE audit_entry
(
    audit_Entry_Id   INTEGER,
    change_By        VARCHAR2 (30), -- User who made the change
    change_TS        TIMESTAMP,     -- TS at which the change was made
    table_Name       VARCHAR2 (30), -- Name of table on which change was made
    column_Name      VARCHAR2 (30), -- Name of column in that table
    primary_key_id   INTEGER,       -- The PK or ID of the row which was changed
    old_clob         CLOB,
    new_clob         CLOB,
    old_TS           TIMESTAMP,
    new_TS           TIMESTAMP,
    old_number       NUMBER (36, 2),
    new_number       NUMBER (36, 2)
)

最后oldnew列将存储适当数据类型的旧值和新值。您还可以根据需要改进表格。然后,在表上构建触发器以跟踪更改并相应地将值插入audit_entry表。