今天快下班的时候有一个同事问我一个存储过程的权限是否做过修改。我简单看了下发现这个滚出过程已经是很久以前创建的了,一直没有做过修改,所以就反馈给 他了。但是他过了一会问我说,他通过数据字典查看,没有找到这个存储过程,想让我帮忙看看是不是因为权限的原因,因为他们调用这个存储过程有一些问题。
同事发过来的语句类似这样的形式:
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
可以看到这个时候存储过程就有值了。这样来理解这个视图就会明白多了。