活动预告

关于all_procedures的问题分析

杨建荣 2016-07-16 11:56:00

今天快下班的时候有一个同事问我一个存储过程的权限是否做过修改。我简单看了下发现这个滚出过程已经是很久以前创建的了,一直没有做过修改,所以就反馈给他了。但是他过了一会问我说,他通过数据字典查看,没有找到这个存储过程,想让我帮忙看看是不是因为权限的原因,因为他们调用这个存储过程有一些问题。

同事发过来的语句类似这样的形式:

SQL> select *from all_procedures where procedure_name like 'insert%cn';

no rows selected

我一看这个语句肯定是查不出结果啊。因为在数据库里面显示都是大写的。所以改为了大写继续查看,奇怪的是竟然显示0条记录。

为了更精确,我直接输入了存储过程的完整名字。但是奇怪的是竟然还是没有任何结果。

SQL> select *from all_procedures where procedure_name='INSERT_BILL_CN';

no rows selected

确认了环境之后,我感觉这个问题一定哪个细节之处存在一些差别。

于是我使用了dba_procedures,但是奇怪的是结果依旧是返回0行

SQL> select *from dba_procedures where procedure_name='INSERT_BILL_CN';

no rows selected

如果对用户的权限存在疑问,我可以确定的是我使用的可是超级DBA SYS

SQL> show user

USER is "SYS"

那是不是存储过程确实不存在呢,使用DESC可以迅速验证我最开始的检查是没有问题的。

SQL> desc test.INSERT_BILL_CN

PROCEDURE test.INSERT_BILL_CN

 Argument Name                  Type                    In/Out Default?

 ------------------------------ ----------------------- ------ --------

 SDATE                          VARCHAR2                IN

 EDATE                          VARCHAR2                IN

 FLAG                           NUMBER                  IN     DEFAULT

到这里确实奇怪了,于是我这样来推理,输出用户下所有的存储过程

SQL> select procedure_name from all_procedures where owner='TEST';

PROCEDURE_NAME

------------------------------

。。。

但是奇怪的是存储过程显示都是为空,这可让我有些疑惑了。我多输出了一个object_name字段。

SQL>SELECT OBJECT_NAME,PROCEDURE_NAME,OBJECT_ID,OBJECT_TYPE FROM DBA_PROCEDURES WHERE OWNER='TLBB'

OBJECT_NAME                    PROCEDURE_  OBJECT_ID OBJECT_TYPE

------------------------------ ---------- ---------- -------------

TEST_TURNCARD_STAT                               73993 PROCEDURE

INSERT_CONSUME_INFO_CN1                        72719 PROCEDURE

INSERT_BILL_CN1                         72600 PROCEDURE

INSERT_CN_TEST_TEST                     71176 PROCEDURE

...

这个时候我算是看明白了,procedure_name为空,但是object_name显示的结果是我们期望之中的procedure_name

为什么这么蹊跷呢。我打开文档查看是否对于字段的理解存在一些偏差。

从字段来看,感觉还是存在着偏差,all_procedures是会包括函数,存储过程,包的信息,这个视图的定义还是不大清晰啊,尤其是字段的含义,让人看了有二义性。

那什么时候procedure_name有值呢,可以看看这个简单的例子。

我们通过all_procedures看看dbms_stats的结构

SQL>SELECT OBJECT_NAME,PROCEDURE_NAME,OBJECT_ID,OBJECT_TYPE FROM DBA_PROCEDURES WHERE PROCEDURE_NAME IS NOT NULL AND OBJECT_NAME LIKE 'DBMS_STATS' AND ROWNUM<10;

OBJECT_NAME                    PROCEDURE_NAME                  OBJECT_ID OBJECT_TYPE

------------------------------ ------------------------------ ---------- -------------

DBMS_STATS                     PREPARE_COLUMN_VALUES                4354 PACKAGE

DBMS_STATS                     PREPARE_COLUMN_VALUES                4354 PACKAGE

DBMS_STATS                     PREPARE_COLUMN_VALUES                4354 PACKAGE

DBMS_STATS                     PREPARE_COLUMN_VALUES                4354 PACKAGE

DBMS_STATS                     PREPARE_COLUMN_VALUES                4354 PACKAGE

DBMS_STATS                     PREPARE_COLUMN_VALUES                4354 PACKAGE

DBMS_STATS                     PREPARE_COLUMN_VALUES_NVARCHAR       4354 PACKAGE

可以看到这个时候存储过程就有值了。这样来理解这个视图就会明白多了。