yangtingkun
===========================================================
OBJECT_ID的重用
===========================================================

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的重用只对过程、函数和包有效,而表、索引等其他类型的对象没有这个特性。

yangtingkun 发表于:2008.03.22 20:59 ::分类: ( ORACLE ) ::阅读:(377次) :: 评论 (2)
re: OBJECT_ID的重用 [回复]

其实这就是NON-EXISTENT的一个表现.
关联sys.obj$表中的type可以给puber们一个更清晰的解释

thoms zhang 评论于: 2008.03.23 17:10
re: OBJECT_ID的重用 [回复]

全都写在一篇文章中,篇幅就太长了,一天的精力也不够。

在http://yangtingkun.itpub.net/post/468/458030中对问题进行比较详细的分析。

yangtingkun 评论于: 2008.03.23 21:11

发表评论
标题

在此添加评论
表情符号: smile laughing tongue angry crying sad wassat wink

称呼

邮箱地址(可选)

个人主页(可选)

 authimage


切换风格
新闻聚合
博客日历
文章归档...
最新发表...
最新评论...
最多阅读文章...
最多评论文章...
博客统计...
Blog信息
网站链接...