我对触发器很陌生,所以显然我在某处做错了.我正在处理一个报告表,它将从原始表中获取数据.为简单起见,假设有一个表,然后有一个报告表.
原始表(orig_tab)
CREATE TABLE orig_tab ( PK NUMBER(8) not null,NAME VARCHAR2(20),); INSERT INTO orig_tab (PK,NAME) VALUES (1,'AAA'); INSERT INTO orig_tab (PK,NAME) VALUES (2,'BBB'); INSERT INTO orig_tab (PK,NAME) VALUES (3,'CCC');
然后是报告表(rep_tab)
CREATE TABLE rep_tab ( PK NUMBER(8) not null,);
现在,从用户界面,有人更改记录2的值.显然,这应该被视为报表的插入(因为此记录不存在).然后在一段时间后,值会更改,因此它是报告表的更新案例.
问题:我怎么能做出这种触发?我认为这是一个合并的州议案例.
这就是我所做的:
create or replace trigger vr_reporting_trigger after update on orig_tab for each row begin MERGE INTO rep_tab d USING (SELECT pk FROM orig_tab) s ON (d.pk = s.pk) WHEN MATCHED THEN UPDATE SET d.pk = s.pk,d.name = s.name WHEN NOT MATCHED THEN INSERT (d.pk,d.name) VALUES (s.pk,s.name); end vr_reporting_trigger;
有什么建议或建议可以帮助我解决这个问题吗?谢谢.
解决方法
在先前的答案中有一些未处理的角落案例.
如果插入行时报告表中已存在匹配的pk,该怎么办? (我们通常不会期望会发生这种情况,但请考虑如果有人从orig_tab中删除了一行,然后再次插入它会发生什么.(这是在生产中出现的问题,而不是在测试中,在最不合时宜的时间.现在更好地为它做好计划.)
BEGIN IF inserting THEN -- insure we avoid duplicate key exception with a NOT EXISTS predicate INSERT INTO rep_tab(pk,name) SELECT :new.pk,:new.name FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM rep_tab WHERE pk = :new.pk); -- if row already existed,there's a possibility that name does not match UPDATE rep_tab t SET t.name = :new.name WHERE t.pk = :new.pk; -- could improve efficiency of update by checking if update is actually -- needed using a nullsafe comparison ( t.name <=> :new.name ); ELSIF updating THEN -- handle updates to pk value (note: the row to be updated may not exist -- so we need to fallthru to the merge) IF :new.pk <> :old.pk THEN UPDATE rep_tab t SET t.pk = :new.pk,t.name = :new.name WHERE t.pk = :old.pk ; END IF; MERGE INTO rep_tab d USING DUAL ON (d.pk = :old.pk) WHEN MATCHED THEN UPDATE SET d.name = :new.name WHEN NOT MATCHED THEN INSERT (d.pk,d.name) VALUES (:new.pk,:new.name); END IF; END;