ITPub博客

首页 > Linux操作系统 > Linux操作系统 > Oracle11gr2新增版本功能(三)

Oracle11gr2新增版本功能(三)

原创 Linux操作系统 作者:yangtingkun 时间:2009-11-30 23:56:17 0 删除 编辑

在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/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
暂无介绍

注册时间:2007-12-29

  • 博文量
    1964
  • 访问量
    11076238