oracle編譯物件失效

zlingyi發表於2015-02-12

今日發現主庫使用查詢使用者查詢檢視的時候出現編譯物件失效的情況,查詢表則無此現象,在網上找到相關的解釋和解決方法

在日常資料庫維護過程中,我們會發現資料庫中一些物件(包Package、儲存過程Procedure、函式Function、檢視View、同義詞.....)會失效,呈現無效狀態(INVALID)。有時候需要定期檢查資料庫中存在哪些失效物件,對於存在異常的物件需要重新編譯,有些自動失效的物件,一般會在下次呼叫的時候,會被重新編譯,所以這些不需要人工干預。那麼為什麼物件突然會失效呢?又如何快速、高效的編譯失效物件呢?哪些失效的物件不需要我們去重新編譯呢?

資料庫物件失效原因

資料庫物件失效的原因很多,下面大致歸納了一些常見的原因(有些漏掉的,希望大家補充):

1: 當被引用物件的結構變更時,都會使得相關的依賴物件轉變為INVALID狀態。

資料庫中的物件(儲存過程,函式,包,檢視,觸發器),它們往往需要直接或者間接的引用其它物件,物件的依賴包括直接和間接二種,其中直接依賴是指儲存物件直接依賴於被引用物件,而間接依賴是指物件間接依賴於被引用物件

要檢視被引用的物件,可以透過下面SQL檢視

select * from dba_dependencies where name='&objectname';
    
select * from all_dependencies where name='&objectname';
 
select * from user_dependencies where name='&objectname';

舉個簡單例子,檢視V_TEST引用了表TEST,TEST表修改了表結構時,會導致檢視V_TEST變為無效物件。

SQL> CREATE TABLE TEST ( ID NUMBER(10));
 
Table created.
 
SQL> CREATE VIEW V_TEST AS SELECT * FROM TEST;
 
View created.
 
SQL> SELECT OBJECT_NAME, STATUS FROM DBA_OBJECTS WHERE OBJECT_NAME='V_TEST';
 
OBJECT_NAME STATUS
 
------------------- ----------------
 
V_TEST VALID
 
--修改表結構,增加一個欄位NAME後,檢視V_TEST變為無效
 
SQL> ALTER TABLE TEST ADD NAME VARCHAR(12);
 
Table altered.
 
SQL> SELECT OBJECT_NAME, STATUS FROM DBA_OBJECTS WHERE OBJECT_NAME='V_TEST';
 
OBJECT_NAME STATUS
 
------------------- ----------------
 
V_TEST INVALID
 
--查詢檢視V_TEST後,資料庫會重新編譯檢視
 
SQL> SELECT * FROM V_TEST;
 
no rows selected
 
SQL> SELECT OBJECT_NAME, STATUS FROM DBA_OBJECTS WHERE OBJECT_NAME='V_TEST';
 
OBJECT_NAME STATUS
 
------------------- ----------------
 
V_TEST VALID
 

其實不管檢視,像儲存過程,函式、包等,如果程式碼本身沒有什麼錯誤,只是引用的物件發生了變化。也會失效。但並不影響呼叫,因為ORACLE在呼叫時會自動重新編譯的,如果其它物件變化後導致編譯有錯誤。這時呼叫時重新編譯後也是錯誤並處於失效狀態,所以呼叫會出錯。

2:釋出SQL指令碼時(包、儲存過程、函式等),沒有充分測試,編譯時出錯,這時物件變為無效。

3: 資料庫升級、遷移時,出現大量無效物件(本質原因,個人臆測歸結為原因1)。

4: 諸如此類各種情況:例如,Oracle 會自動維護分割槽索引,對於全域性索引,如果在對分割槽表操作時,沒有指定update index,則會導致全域性索引失效,需要重建。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28686045/viewspace-1433945/,如需轉載,請註明出處,否則將追究法律責任。

相關文章