联系:手机/微信(+86 17813235971) QQ(107644445)
作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]
有网友询问了,一个多表关联视图,怎么实现dml操作,其实这个可以使用INSTEAD OF触发器实现
1、准备实验环境
创建两个表和一个视图(两表union关联),并各自插入一条模拟数据
C:\Users\XIFENFEI>sqlplus chf/xifenfei SQL*Plus: Release 11.2.0.1.0 Production on 星期日 12月 18 10:57:05 2011 Copyright (c) 1982, 2010, Oracle. All rights reserved. 连接到: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production With the Partitioning, Oracle Label Security, OLAP, Data Mining, Oracle Database Vault and Real Application Testing options SQL> CREATE TABLE XFF_T1 (ID NUMBER PRIMARY KEY, NAME VARCHAR2(30)); 表已创建。 SQL> CREATE TABLE XFF_T2 (ID NUMBER PRIMARY KEY, NAME VARCHAR2(30)); 表已创建。 SQL> CREATE VIEW V_XFF_T AS SELECT * FROM XFF_T1 UNION ALL SELECT * FROM XFF_T2; 视图已创建。 SQL> INSERT INTO XFF_T1 VALUES (1, 'XFF_T1'); 已创建 1 行。 SQL> INSERT INTO XFF_T2 VALUES (2, 'XFF_T2'); 已创建 1 行。 SQL> COMMIT; 提交完成。 SQL> SELECT * FROM V_XFF_T; ID NAME ---------- ------------------------------ 1 XFF_T1 2 XFF_T2
2、尝试dml操作视图
插入、删除、更新dml操作全部失败
SQL> INSERT INTO V_XFF_T VALUES (3, 'V_XFF_T', ); INSERT INTO V_XFF_T VALUES (3, 'V_XFF_T') * 第 1 行出现错误: ORA-01732: 此视图的数据操纵操作非法 SQL> DELETE FROM V_XFF_T WHERE ID=2; DELETE FROM V_XFF_T WHERE ID=2 * 第 1 行出现错误: ORA-01732: 此视图的数据操纵操作非法 SQL> UPDATE V_XFF_T SET NAME='XIFENFEI' WHERE ID=3; UPDATE V_XFF_T SET NAME='XIFENFEI' WHERE ID=2 * 第 1 行出现错误: ORA-01732: 此视图的数据操纵操作非法
3、创建INSTEAD OF触发器
SQL> CREATE OR REPLACE TRIGGER INSTEADOF_T 2 INSTEAD OF INSERT OR UPDATE OR DELETE ON V_XFF_T 3 FOR EACH ROW 4 BEGIN 5 IF INSERTING THEN 6 INSERT INTO XFF_T2 VALUES (:NEW.ID, :NEW.NAME); 7 ELSIF UPDATING THEN 8 UPDATE XFF_T2 SET ID = :NEW.ID, NAME = :NEW.NAME 9 WHERE ID = :OLD.ID; 10 ELSIF DELETING THEN 11 DELETE XFF_T2 WHERE ID = :OLD.ID; 12 END IF; 13 END; 14 / 触发器已创建
4、重试dml操作
使用基于INSTEAD OF触发器实现了对复杂视图的dml操作
SQL> INSERT INTO V_XFF_T VALUES (3, 'V_XFF_T'); 已创建 1 行。 SQL> SELECT * FROM V_XFF_T; ID NAME ---------- ------------------------------ 1 XFF_T1 2 XFF_T2 3 V_XFF_T SQL> DELETE FROM V_XFF_T WHERE ID=2; 已删除 1 行。 SQL> SELECT * FROM V_XFF_T; ID NAME ---------- ------------------------------ 1 XFF_T1 3 V_XFF_T SQL> UPDATE V_XFF_T SET NAME='XIFENFEI' WHERE ID=3; 已更新 1 行。 SQL> SELECT * FROM V_XFF_T; ID NAME ---------- ----------------------------- 1 XFF_T1 3 XIFENFEI SQL> COMMIT; 提交完成。
5、查询基表情况
因为编写的INSTEAD OF触发器是对XFF_T2表作用,所以所有关于该视图的操作,都映射到XFF_T2表中
SQL> SELECT * FROM XFF_T1; ID NAME ---------- ------------------------------ 1 XFF_T1 SQL> SELECT * FROM XFF_T2; ID NAME ---------- ------------------------------ 3 XIFENFEI