OBJECT_ID的重用

yangtingkun發表於2008-03-22

Oracle對於過程會重用OBJECT_ID。這裡的過程是指過程、函式、包和物件的總稱。

 

 

看一個簡單的例子:

SQL> CONN YANGTK/YANGTK
SQL> CREATE OR REPLACE PROCEDURE P_TEST AS
  2  BEGIN
  3  NULL;
  4  END;
  5  /

過程已建立。

SQL> SELECT OBJECT_ID, OBJECT_NAME FROM DBA_OBJECTS WHERE OBJECT_NAME = 'P_TEST';

 OBJECT_ID OBJECT_NAME
---------- ------------------------------
     53169 P_TEST

SQL> CREATE OR REPLACE PROCEDURE P_TEST AS
  2  BEGIN
  3  NULL;
  4  END;
  5  /

過程已建立。

SQL> SELECT OBJECT_ID, OBJECT_NAME FROM DBA_OBJECTS WHERE OBJECT_NAME = 'P_TEST';

 OBJECT_ID OBJECT_NAME
---------- ------------------------------
     53169 P_TEST

SQL> DROP PROCEDURE P_TEST;

過程已刪除。

SQL> CREATE OR REPLACE PROCEDURE P_TEST AS
  2  BEGIN
  3  NULL;
  4  END;
  5  /

過程已建立。

SQL> SELECT OBJECT_ID, OBJECT_NAME FROM DBA_OBJECTS WHERE OBJECT_NAME = 'P_TEST';

 OBJECT_ID OBJECT_NAME
---------- ------------------------------
     53169 P_TEST

對於CREATE OR REPLACE操作,並不會改變物件的OBJECT_ID,但是對於DROPCREATE操作來說,Oracle也可以重用原來的OBJECT_ID

而且這個重用並不需要刪除操作和建立操作之間有任何的連續性:

SQL> DROP PROCEDURE P_TEST;

過程已刪除。

SQL> CREATE PROCEDURE P_TEST1 AS
  2  BEGIN
  3  NULL;
  4  END;
  5  /

過程已建立。

SQL> SELECT OBJECT_ID, OBJECT_NAME FROM DBA_OBJECTS WHERE OBJECT_NAME LIKE 'P_TEST%';

 OBJECT_ID OBJECT_NAME
---------- ------------------------------
     55490 P_TEST1

SQL> CREATE PROCEDURE P_TEST AS
  2  BEGIN
  3  NULL;
  4  END;
  5  /

過程已建立。

SQL> SELECT OBJECT_ID, OBJECT_NAME FROM DBA_OBJECTS WHERE OBJECT_NAME LIKE 'P_TEST%';

 OBJECT_ID OBJECT_NAME
---------- ------------------------------
     53169 P_TEST
     55490 P_TEST1

從上面的結果也可以看出,其實P_TEST過程重用的OBJECT_ID是很早之前產生的,顯然這個例子開始時候建立P_TEST的時候,已經是重用OBJECT_ID了。

這說明OBJECT_ID的重用和資料庫的會話沒有關係。因為這是一個新登陸的會話,執行的過程建立就會重用OBJECT_ID。那麼資料庫例項的狀態是否會影響OBJECT_ID的重用呢:

SQL> DROP PROCEDURE P_TEST;

過程已刪除。

SQL> CONN / AS SYSDBA
已連線。
SQL> SHUTDOWN IMMEDIATE
資料庫已經關閉。
已經解除安裝資料庫。
ORACLE
例程已經關閉。
SQL> STARTUP
ORACLE
例程已經啟動。

Total System Global Area  603979776 bytes
Fixed Size                  1249332 bytes
Variable Size             159387596 bytes
Database Buffers          436207616 bytes
Redo Buffers                7135232 bytes
資料庫裝載完畢。
資料庫已經開啟。

SQL> CONN YANGTK/YANGTK
已連線。
SQL> CREATE PROCEDURE P_TEST AS
  2  BEGIN
  3  NULL;
  4  END;
  5  /

過程已建立。

SQL> SELECT OBJECT_ID, OBJECT_NAME FROM DBA_OBJECTS WHERE OBJECT_NAME LIKE 'P_TEST%';

 OBJECT_ID OBJECT_NAME
---------- ------------------------------
     55496 P_TEST
     55490 P_TEST1

看來OBJECT_ID的重用與Oracle例項中記憶體裡面的某些記錄有關。而且,Oracle重用OBJECT_ID似乎只關心名稱而不關心過程的內容:

SQL> DROP PROCEDURE P_TEST;

過程已刪除。

SQL> CREATE OR REPLACE PROCEDURE P_TEST AS
  2  BEGIN
  3  DBMS_OUTPUT.PUT_LINE('THIS PROCEDURE IS DIFFERENENT!');
  4  END;
  5  /

過程已建立。

SQL> SELECT OBJECT_ID, OBJECT_NAME FROM DBA_OBJECTS WHERE OBJECT_NAME = 'P_TEST';

 OBJECT_ID OBJECT_NAME
---------- ------------------------------
     55496 P_TEST

SQL> DROP PROCEDURE P_TEST;

過程已刪除。

SQL> CREATE OR REPLACE FUNCTION P_TEST RETURN NUMBER AS
  2  BEGIN
  3  RETURN 1;
  4  END;
  5  /

函式已建立。

SQL> SELECT OBJECT_ID, OBJECT_NAME FROM DBA_OBJECTS WHERE OBJECT_NAME = 'P_TEST';

 OBJECT_ID OBJECT_NAME
---------- ------------------------------
     55496 P_TEST

SQL> DROP FUNCTION P_TEST;

函式已刪除。

SQL> CREATE PACKAGE P_TEST AS
  2  PROCEDURE P_ABC;
  3  END;
  4  /

程式包已建立。

SQL> SELECT OBJECT_ID, OBJECT_NAME FROM DBA_OBJECTS WHERE OBJECT_NAME = 'P_TEST';

 OBJECT_ID OBJECT_NAME
---------- ------------------------------
     55496 P_TEST

從這個例子以可以看到,Oracle不止不關心前後兩次內容是否相同,連是否相同物件都不關心。不管過程、函式還是包,只要名稱相同,就可以重用OBJECT_ID

SQL> DROP PACKAGE P_TEST;

程式包已刪除。

SQL> CREATE PROCEDURE USER_A.P_TEST AS
  2  BEGIN
  3  NULL;
  4  END;
  5  /

過程已建立。

SQL> SELECT OBJECT_ID, OWNER, OBJECT_NAME FROM DBA_OBJECTS WHERE OBJECT_NAME = 'P_TEST';

 OBJECT_ID OWNER                          OBJECT_NAME
---------- ------------------------------ ------------------------------
     55497 USER_A                         P_TEST

除了名稱,過程的OWNER顯然也是Oracle關心的物件。

根據上面的特點,推測Oracle在記憶體中記錄了每個使用者的每個過程對應的OBJECT_ID,而這個OBJECT_ID的記錄並沒有隨著過程的刪除而刪掉,因此同名的過程重新建立時,就可以重用這個OBJECT_ID

OBJECT_ID的重用只對過程、函式和包有效,而表、索引等其他型別的物件沒有這個特性。

 

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

相關文章