在11.2中,Oracle数据库引入的版本的概念,这为应用程序的升级提供了极大的方便。
这篇简单描述版本视图。
Oracle11gr2新增版本功能(一):http://yangtingkun.itpub.net/post/468/491458
Oracle11gr2新增版本功能(二):http://yangtingkun.itpub.net/post/468/491473
上文提到了,支持版本功能的对象包括:SYNONYM、VIEW、PROCEDURE、FUNCTION、PACKAGE、TYPE、TRIGGER和LIBRARY。
可以看到存储数据最关键的部分TABLE并不支持版本的功能,如果系统程序的升级只是涉及PROCEDURE、VIEW以及SYNONYM的修改,那么版本功能可以提供很好的支持。但是更多的升级可能要修改表的结构,尤其是新增列,更是一个常见的需求,那么数据库的版本功能如何屏蔽表结构对应用程序的影响呢,答案就是版本视图。
对于经常需要进行结构变更的表,可以利用版本视图来代替:
SQL> SELECT * FROM V$VERSION;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
CORE 11.2.0.1.0 Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production
SQL> CREATE TABLE T
2 (ID NUMBER,
3 NAME VARCHAR2(30));
表已创建。
如果T表在新的版本中需要修改表结构,那么如何才能避免T表结构的修改对当前版本的影响呢,这时应该创建版本视图。
SQL> ALTER TABLE T RENAME TO T_TABLE;
表已更改。
SQL> CREATE EDITIONING VIEW T
2 AS SELECT ID, NAME
3 FROM T_TABLE;
视图已创建。
SQL> DESC T
名称 是否为空? 类型
----------------------------------------- -------- ----------------------------
ID NUMBER
NAME VARCHAR2(30)
SQL> SELECT SYS_CONTEXT('USERENV', 'CURRENT_EDITION_NAME') FROM DUAL;
SYS_CONTEXT('USERENV','CURRENT_EDITION_NAME')
--------------------------------------------------------------------------------
ORA$BASE
SQL> ALTER SESSION SET EDITION = MY_EDITION;
会话已更改。
SQL> ALTER TABLE T_TABLE ADD AGE NUMBER(3);
表已更改。
SQL> CREATE EDITIONING VIEW T
2 AS SELECT ID, NAME, AGE
3 FROM T_TABLE;
CREATE EDITIONING VIEW T
*
第 1 行出现错误:
ORA-00955: 名称已由现有对象使用
SQL> DESC T
名称 是否为空? 类型
----------------------------------------- -------- ----------------------------
ID NUMBER
NAME VARCHAR2(30)
SQL> CREATE OR REPLACE EDITIONING VIEW T
2 AS SELECT ID, NAME, AGE
3 FROM T_TABLE;
视图已创建。
SQL> DESC T
名称 是否为空? 类型
----------------------------------------- -------- ----------------------------
ID NUMBER
NAME VARCHAR2(30)
AGE NUMBER(3)
SQL> ALTER SESSION SET EDITION = ORA$BASE;
会话已更改。
SQL> DESC T
名称 是否为空? 类型
----------------------------------------- -------- ----------------------------
ID NUMBER
NAME VARCHAR2(30)
可以看到,有了版本视图的支持,就可以屏蔽表结构的修改对版本的影响了。
需要注意,版本视图和普通的视图有很多的区别。首先版本视图只能访问一张表的部分列或全部列,而且视图不能包含WHERE查询条件,不能包括GROUP BY、HAVING、MODULE、START WITH、CONNECT BY等语句,不能包括UNIQUE、DISTINT或UNION、MINUS、INTERSECT等改变记录数的语句。而且在任意一个版本中一张表只能包含一个版本视图,版本视图上的触发器只在视图修改的时候触发,视图的基表的修改并不会触发版本视图上的触发器,且版本视图上不能建立INSTEAD OF触发器。
下面看看版本视图的一些特点:
SQL> CREATE EDITIONING VIEW V_T
2 AS SELECT ID, NAME
3 FROM T_TABLE;
FROM T_TABLE
*
第 3 行出现错误:
ORA-42300: 已在此表上定义版本化视图
SQL> CREATE OR REPLACE EDITIONING VIEW T
2 AS SELECT ID, NAME, COUNT(*) COUNT
3 FROM T_TABLE
4 GROUP BY ID, NAME;
AS SELECT ID, NAME, COUNT(*) COUNT
*
第 2 行出现错误:
ORA-00923: 未找到要求的 FROM 关键字
SQL> CREATE OR REPLACE EDITIONING VIEW T
2 AS SELECT ID, NAME
3 FROM T_TABLE
4 WHERE ID = 1;
WHERE ID = 1
*
第 4 行出现错误:
ORA-00933: SQL 命令未正确结束
SQL> CREATE TRIGGER T_TABLE
2 BEFORE INSERT ON T_TABLE
3 FOR EACH ROW
4 BEGIN
5 DBMS_OUTPUT.PUT_LINE('INSERT INTO T_TABLE WITH ID:' || :NEW.ID);
6 END;
7 /
触发器已创建
SQL> CREATE TRIGGER T
2 BEFORE INSERT ON T
3 FOR EACH ROW
4 BEGIN
5 DBMS_OUTPUT.PUT_LINE('INSERT INTO T WITH ID:' || :NEW.ID);
6 END;
7 /
触发器已创建
SQL> SET SERVEROUT ON
SQL> INSERT INTO T VALUES (1, 'A');
INSERT INTO T WITH ID:1
INSERT INTO T_TABLE WITH ID:1
已创建 1 行。
SQL> INSERT INTO T_TABLE VALUES (2, 'B', 15);
INSERT INTO T_TABLE WITH ID:2
已创建 1 行。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/4227/viewspace-621054/ ,如需转载,请注明出处,否则将追究法律责任。