2012-05-29 24 views
2

我想列出在给定模式中使用重载的所有存储过程。所有的程序都在包内。我可以使用下面的SQL几乎到达那里(任何与proc_count> 1)。如何区分Oracle元数据中的过程和函数?

select 
    object_name, procedure_name, count(procedure_name) as proc_count 
from 
    all_procedures     
where 
    owner = 'SCHEMA_NAME' 
group by 
    object_name, procedure_name 
order by proc_count desc 

但是似乎没有办法一个名为“ask_version”功能和一个名为“ask_version”我需要在我的情况做程序之间进行区分。这种情况是我们的中间件在调用使用重载的过程时遇到问题。我需要对这种情况发生的地点进行影响分析。我们从不直接调用函数,因此需要将它们隔离起来

有没有我失踪的东西?

回答

6

all_arguments似乎有帮助。对于一个函数,有一个参数position=0(这是返回值),对于这个参数不存在的过程。

SELECT object_name, procedure_name, t, COUNT(1) AS proc_count 
FROM 
(
    SELECT p.object_name, p.procedure_name, 
     CASE WHEN a.object_id IS NULL THEN 'PROCEDURE' ELSE 'FUNCTION' END AS t 
    FROM all_procedures p 
    LEFT JOIN all_arguments a ON (a.object_id = p.object_id 
          AND a.subprogram_id = p.subprogram_id AND a.position = 0) 
    WHERE p.owner = 'SCHEMA_NAME' 
) 
GROUP BY object_name, procedure_name, t 
ORDER BY proc_count DESC; 
+0

完美!我确实看过all_arguments视图,但没有发现该模式。谢谢! – barnyr

2

由于Oracle将软件包作为离散对象从独立函数和过程存储,所以这有点棘手。

您可以通过查看ALL_ARGUMENTS中的参数元数据来简单说明这一点。函数在位置0处有一个参数来指定返回类型,而过程不会。

另外,通过检查OVERLOAD字段很容易判断某个函数或过程是否有重载。

select P.OBJECT_NAME 
,  P.PROCEDURE_NAME 
,  DECODE(min(a.POSITION), 0, 'Function', 'Procedure') FUNC_OR_PROC 
,  DECODE(NVL(min(P.OVERLOAD), 0), 0, 'No', 'Yes') OVERLOADED 
from ALL_PROCEDURES P 
,  ALL_ARGUMENTS a 
where P.OWNER = 'FLOWS_030000' 
and P.OBJECT_NAME = a.PACKAGE_NAME 
and P.PROCEDURE_NAME = a.OBJECT_NAME 
group by P.OBJECT_NAME, P.PROCEDURE_NAME 
order by 1,2;