一个INSTEAD OF TRIGGER的例子

今天在ITPUB上帮朋友写了一个INSTEAD OF触发器的小例子,在这里简单记录一下。


对于复杂的视图,无法直接对视图进行修改。或者在某些情况下,需要将对视图的修改转化为另外一种操作,这种情况下可以使用INSTEAD OF TRIGGER

看一个简单的例子,下面建立一个UNION ALL视图,其中T1表是不能修改的,对视图T所有的修改都重定位到T2上。

SQL> CREATE TABLE T1 (ID NUMBER PRIMARY KEY, NAME VARCHAR2(30), OTHERS VARCHAR2(30));

表已创建。

SQL> CREATE TABLE T2 (ID NUMBER PRIMARY KEY, NAME VARCHAR2(30), OTHERS VARCHAR2(30));

表已创建。

SQL> CREATE VIEW T AS SELECT * FROM T1 UNION ALL SELECT * FROM T2;

视图已创建。

SQL> INSERT INTO T1 VALUES (1, 'T1', 'TEST');

已创建 1 行。

SQL> INSERT INTO T2 VALUES (2, 'T2', 'TEST T2');

已创建 1 行。

SQL> COMMIT;

提交完成。

SQL> SELECT * FROM T;

ID NAME OTHERS
---------- ------------------------------ ------------------------------
1 T1 TEST
2 T2 TEST T2

SQL> INSERT INTO T VALUES (3, 'T', 'TEST AGAIN');
INSERT INTO T VALUES (3, 'T', 'TEST AGAIN')
*
1 行出现错误:
ORA-01732:
此视图的数据操纵操作非法


SQL> DELETE T;
DELETE T
*
1 行出现错误:
ORA-01732:
此视图的数据操纵操作非法


SQL> UPDATE T SET OTHERS = 'UPDATED' WHERE ID = 2;
UPDATE T SET OTHERS = 'UPDATED' WHERE ID = 2
*
1 行出现错误:
ORA-01732:
此视图的数据操纵操作非法

下面建立INSTEAD OF触发器:

SQL> CREATE OR REPLACE TRIGGER INSTEADOF_T
2 INSTEAD OF INSERT OR UPDATE OR DELETE ON T
3 REFERENCES OLD AS OLD NEW AS NEW
4 FOR EACH ROW
5 BEGIN
6 IF INSERTING THEN
7 INSERT INTO T2 VALUES (:NEW.ID, :NEW.NAME, :NEW.OTHERS);
8 ELSIF UPDATING THEN
9 UPDATE T2 SET ID = :NEW.ID, NAME = :NEW.NAME, OTHERS = :NEW.OTHERS
10 WHERE ID = :OLD.ID;
11 ELSIF DELETING THEN
12 DELETE T2 WHERE ID = :OLD.ID;
13 END IF;
14 END;
15 /

触发器已创建

SQL> INSERT INTO T VALUES (3, 'T', 'TEST AGAIN');

已创建 1 行。

SQL> SELECT * FROM T;

ID NAME OTHERS
---------- ------------------------------ ------------------------------
1 T1 TEST
2 T2 TEST T2
3 T TEST AGAIN

SQL> SELECT * FROM T1;

ID NAME OTHERS
---------- ------------------------------ ------------------------------
1 T1 TEST

SQL> SELECT * FROM T2;

ID NAME OTHERS
---------- ------------------------------ ------------------------------
2 T2 TEST T2
3 T TEST AGAIN

SQL> UPDATE T SET OTHERS = 'UPDATED';

已更新3行。

SQL> SELECT * FROM T;

ID NAME OTHERS
---------- ------------------------------ ------------------------------
1 T1 TEST
2 T2 UPDATED
3 T UPDATED

SQL> DELETE T;

已删除3行。

SQL> SELECT * FROM T;

ID NAME OTHERS
---------- ------------------------------ ------------------------------
1 T1 TEST

SQL> SELECT * FROM T2;

未选定行

INSTEAD OF触发器已经发挥了作用,将所有对视图T的修改都重定向到T2上,不过UPDATE的修改采用了偷懒的写法,这里并没有对修改的列进行检测,而是采用了全部更新的方法。这样可以减少代码量,但是会对一些没有发生修改的字段进行更新,导致REDOUNDO的增加。如果T2表中还存在基于字段更新的触发器的话,就不能使用这种办法了。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/4227/viewspace-69377/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/4227/viewspace-69377/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值