Oracle Trigger для вставки / обновления в другую таблицу - PullRequest
1 голос
/ 02 апреля 2019

По сути, я хотел создать триггер оракула, который будет отслеживать вставку / обновление в таблицу, и я хотел вставлять только эти измененные записи в новую таблицу ежедневно. Эти новые данные таблицы будут использоваться для моего ежедневное обновление данных (больше похоже на подход 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 голосов
/ 02 апреля 2019

На первый взгляд я вижу одну проблему в этом триггере, когда вставляется новая запись, 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))
0 голосов
/ 02 апреля 2019

Ваш триггер в его нынешнем виде имеет слишком много ненужных конструкций, от которых вы должны избавиться.Все, что вам нужно (как вы подтвердили в комментариях), это один оператор вставки в 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

...