Oracle 触发器插入/更新到另一个 table
Oracle Trigger to insert /update to another table
基本上,我想创建一个 oracle 触发器,它将跟踪 table 中的 Insert/Updates,我想将这些更改的记录单独插入到新的 table 中每日 basis.This 新 table 数据将用于我的每日数据刷新(更像是 CDC 方法)
我正在使用以下代码。我的期望是当我的客户 table 得到 INSERT/UPDATED 时,该记录应该在 CUSTOMER_D table.But 中可用 我在下面的代码
中遗漏了一些东西
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;
您当前形式的触发器包含太多不必要的结构,您应该将其删除。每当从 customers
table.
添加或插入记录时,您所需要的(正如您在评论中确认的那样)就是将一条插入语句插入 customers_d
我建议您添加另一列指示交易时间 -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 ;
/
乍一看,当插入新记录时,我可以看到此触发器中的一个问题,OLD.ID 将为 NULL,因此 WHEN ((OLD.ID <> NEW.ID)
将为 FALSE
,并且不会调用触发器在插入 CUST_TRIG 时。只需添加以下条件:
FOR EACH ROW WHEN ((OLD.ID <> NEW.ID) OR (OLD.ID IS NULL))
基本上,我想创建一个 oracle 触发器,它将跟踪 table 中的 Insert/Updates,我想将这些更改的记录单独插入到新的 table 中每日 basis.This 新 table 数据将用于我的每日数据刷新(更像是 CDC 方法)
我正在使用以下代码。我的期望是当我的客户 table 得到 INSERT/UPDATED 时,该记录应该在 CUSTOMER_D table.But 中可用 我在下面的代码
中遗漏了一些东西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;
您当前形式的触发器包含太多不必要的结构,您应该将其删除。每当从 customers
table.
添加或插入记录时,您所需要的(正如您在评论中确认的那样)就是将一条插入语句插入 customers_d
我建议您添加另一列指示交易时间 -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 ;
/
乍一看,当插入新记录时,我可以看到此触发器中的一个问题,OLD.ID 将为 NULL,因此 WHEN ((OLD.ID <> NEW.ID)
将为 FALSE
,并且不会调用触发器在插入 CUST_TRIG 时。只需添加以下条件:
FOR EACH ROW WHEN ((OLD.ID <> NEW.ID) OR (OLD.ID IS NULL))