Oracle11gr2新增版本功能(三)

yangtingkun發表於2009-11-30

11.2中,Oracle資料庫引入的版本的概念,這為應用程式的升級提供了極大的方便。

這篇簡單描述版本檢視。

Oracle11gr2新增版本功能(一):http://yangtingkun.itpub.net/post/468/491458

Oracle11gr2新增版本功能(二):http://yangtingkun.itpub.net/post/468/491473

 

 

上文提到了,支援版本功能的物件包括:SYNONYMVIEWPROCEDUREFUNCTIONPACKAGETYPETRIGGERLIBRARY

可以看到儲存資料最關鍵的部分TABLE並不支援版本的功能,如果系統程式的升級只是涉及PROCEDUREVIEW以及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 BYHAVINGMODULESTART WITHCONNECT BY等語句,不能包括UNIQUEDISTINTUNIONMINUSINTERSECT等改變記錄數的語句。而且在任意一個版本中一張表只能包含一個版本檢視,版本檢視上的觸發器只在檢視修改的時候觸發,檢視的基表的修改並不會觸發版本檢視上的觸發器,且版本檢視上不能建立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部落格 ” ,連結:http://blog.itpub.net/4227/viewspace-621054/,如需轉載,請註明出處,否則將追究法律責任。

相關文章