Oracle触发器插入/更新到另一个表

时间:2019-04-02 03:23:17

标签: oracle plsql database-trigger

基本上,我想创建一个Oracle触发器,该触发器将跟踪表中的插入/更新,并且我想每天将这些更改的记录单独插入到新表中。该新表数据将用于我的每日数据刷新(更像CDC方法)

我正在使用以下代码。我的期望是当我的CUSTOMER表获得INSERT / UPDATED时,该记录应该在CUSTOMER_D表中可用。但是我在下面的代码中缺少了一些东西

CREATE OR REPLACE TRIGGER CUST_TRIG AFTER INSERT OR UPDATE ON CUSTOMERS
REFERENCING OLD AS OLD NEW AS NEW
FOR EACH ROW WHEN (OLD.ID <> NEW.ID)
begin
  IF INSERTING THEN
    begin
    INSERT INTO CUSTOMERS_D
      (ID, NAME, AGE, ADDRESS, SALARY) values
      (:new.ID, :new.NAME, :new.AGE, :new.ADDRESS, :new.SALARY);
    -- assuming, there is an unique key on id
    exception
      when dup_val_on_index then
        null;
    end;

  ELSIF UPDATING THEN
    IF :NEW.ID = :OLD.ID THEN
      UPDATE CUSTOMERS_D DWT
         SET DWT.ID = :NEW.ID,
             DWT.NAME = :NEW.NAME,
             DWT.AGE = :NEW.AGE,
             DWT.ADDRESS = :NEW.ADDRESS,
             DWT.SALARY = :NEW.SALARY;
    END IF;
    MERGE INTO CUSTOMERS_D D
    USING DUAL
    ON (D.ID = :NEW.ID)
    WHEN MATCHED THEN
      UPDATE SET D.NAME = :NEW.NAME,
             D.AGE = :NEW.AGE,
             D.ADDRESS = :NEW.ADDRESS,
             D.SALARY = :NEW.SALARY
    WHEN NOT MATCHED THEN
      INSERT
        (D.ID, D.NAME, D.AGE, D.ADDRESS, D.SALARY) VALUES
        (:NEW.ID, :NEW.NAME, :NEW.AGE, :NEW.ADDRESS, :NEW.SALARY);
  END IF;

end test;

2 个答案:

答案 0 :(得分:0)

您当前形式的触发器包含太多不必要的构造,您应该摆脱它们。只要在customers_d表中添加或插入一条记录,您所需要的(正如您在注释中所确认的)就是一个插入customers中的插入语句。
我建议您添加另一列来指示交易时间-MODIFIED_TIME

CREATE OR REPLACE TRIGGER CUST_TRIG 
  AFTER INSERT OR UPDATE ON CUSTOMERS 
FOR EACH ROW 
begin
   INSERT INTO CUSTOMERS_D
     (ID, NAME, AGE, ADDRESS, SALARY,modified_time ) 
       values (:new.ID,
       :new.NAME, 
       :new.AGE, 
       :new.ADDRESS, 
       :new.SALARY,
       systimestamp);
end ;
/

DEMO

答案 1 :(得分:0)

乍看之下,当插入新记录时,我会看到此触发器中的一个问题。OLD.ID将为NULL,因此WHEN ((OLD.ID <> NEW.ID)将为FALSE,并且该触发器将不会在INSERT插入CUST_TRIG时被调用。只需添加以下条件:

FOR EACH ROW  WHEN ((OLD.ID <> NEW.ID) OR (OLD.ID IS NULL))