我正在尝试创建一个调试工具:一些提供包名称并为其生成调试包装的东西(具有类似过程的包;这些过程将记录调用,参数值,执行原始过程并记录调用结果)。
通常我做了,但我发现了一个不好的情况:在查看USER_PROCEDURES和USER_ARGUMENTS时,没有默认值的参数和具有null默认值的参数之间没有任何差异。有没有办法区分它?
现在我只是将'default null'放到任何包装器的'in'参数中,但没有一个,但这对我来说并不好。我找到的第二种方法是解析USER_SOURCE,但我猜这通常很讨厌。
===编辑:感谢@phonetic_man,对于Oracle 11,有USER_ARGUMENTS.DEFAULTED列。是否有Oracle 10的决定? ===
答案 0 :(得分:0)
正如@phonetic_man在评论中所述,在11g中,user_arguments
视图有一个defaulted
列。这在早期版本中不存在。在10g中有一个sqljutl
包,as part of the database's Java installation。你可以使用has_default
函数:
desc sys.sqljutl
...
FUNCTION HAS_DEFAULT RETURNS NUMBER
Argument Name Type In/Out Default?
------------------------------ ----------------------- ------ --------
OID NUMBER IN
PROC CHAR IN
SEQ NUMBER IN
OVR NUMBER IN
...
您可以将user_arguments
中的列值传递到该函数中:
select object_name, package_name, argument_name, data_type, defaulted,
sys.sqljutl.has_default(object_id,
case when package_name is null then null else object_name end,
sequence,
nvl(overload, 0)) as defaulted
from user_arguments
where package_name = '<YOUR_PACKAGE>'
and object_name = '<YOUR PROCEDURE>';
case表达式是因为函数执行略有不同的查询,具体取决于传递的对象名是否为null;它只需要为包过程设置,而不是为独立过程设置。 (你可以在$ORACLE_HOME/rdbms/admin/initsqlj.sql
中看到它实际上在做什么。)
create package pack42 as
procedure proc42 (p1 number, p2 varchar2 default null);
end pack42;
/
create package body pack42 as
procedure proc42 (p1 number, p2 varchar2 default null) is
begin
null;
end proc42;
end pack42;
/
select object_name, package_name, argument_name, data_type, -- defaulted,
sys.sqljutl.has_default(object_id,
case when package_name is null then null else object_name end,
sequence,
nvl(overload, 0)) as defaulted
from user_arguments
where package_name = 'PACK42'
and object_name = 'PROC42';
OBJECT_NAME PACKAGE_NAME ARGUMENT_NAME DATA_TYPE DEFAULTED
----------- ------------ ------------- --------- ----------
PROC42 PACK42 P2 VARCHAR2 1
PROC42 PACK42 P1 NUMBER 0
和一个独立的程序:
create procedure proc42 (p1 number, p2 varchar2 default null) as
begin
null;
end;
/
select object_name, package_name, argument_name, data_type, -- defaulted,
sys.sqljutl.has_default(object_id,
case when package_name is null then null else object_name end,
sequence,
nvl(overload, 0)) as defaulted
from user_arguments
where package_name is null
and object_name = 'PROC42';
OBJECT_NAME PACKAGE_NAME ARGUMENT_NAME DATA_TYPE DEFAULTED
----------- ------------ ------------- --------- ----------
PROC42 P2 VARCHAR2 1
PROC42 P1 NUMBER 0
如果有默认值,则返回1,如果没有则返回0。
这也适用于11g,而user_arguments.defaulted
列正在查看相同的基础数据字典信息(argument$.default#
);虽然它被转换为Y / N,你当然可以自己做。
使用11g中的相同包构建,您可以看到两个标志:
select object_name, package_name, argument_name, data_type, defaulted,
sys.sqljutl.has_default(object_id,
case when package_name is null then null else object_name end,
sequence,
nvl(overload, 0)) as defaulted
from user_arguments
where package_name = 'PACK42'
and object_name = 'PROC42';
OBJECT_NAME PACKAGE_NAME ARGUMENT_NAME DATA_TYPE D DEFAULTED
----------- ------------ ------------- --------- - ----------
PROC42 PACK42 P1 NUMBER N 0
PROC42 PACK42 P2 VARCHAR2 Y 1