使用Oracle字典视图发现PL / SQL包级别类型

时间:2011-06-20 11:35:14

标签: oracle dictionary types plsql package

我可以使用字典视图发现在Oracle PL / SQL包中声明的类型吗?即当我宣布这个时:

CREATE OR REPLACE PACKAGE my_types AS
  TYPE t_cursor_type IS REF CURSOR;
  TYPE t_table_type IS TABLE OF some_table%rowtype;
END my_types;

我想正式发现t_cursor_typet_table_type。它们似乎没有列在

SYS.ALL_TYPES

“正式”我的意思是我想要一些“正式的元数据”,即查询USER_SOURCE将无法解决问题。

5 个答案:

答案 0 :(得分:6)

仅从11.1开始。

从手册:

http://download.oracle.com/docs/cd/E11882_01/appdev.112/e17125/adfns_plscope.htm#ADFNS02204

http://download.oracle.com/docs/cd/E11882_01/server.112/e17110/initparams189.htm#REFRN10271

  

PL / Scope是一个编译器驱动的工具,它在程序单元编译时收集PL / SQL源代码中的标识符数据,并使其在静态数据字典视图中可用。收集的数据包括有关标识符类型,用法(声明,定义,参考,调用,分配)以及源代码中每种用法的位置的信息。

样本

CREATE OR REPLACE PACKAGE my_types AS
  TYPE t_cursor_type IS REF CURSOR;
  TYPE t_table_type IS TABLE OF employees%rowtype;
  type t_associative is table number index by  varchar2(20);
END my_types;

alter package  my_types compile plscope_settings='IDENTIFIERS:ALL' reuse settings;

select *
from   user_identifiers ui
where  ui.object_type = 'PACKAGE'
and    ui.usage = 'DECLARATION'
and    ui.usage_context_id = '1';


NAME                           SIGNATURE                        TYPE               OBJECT_NAME                    OBJECT_TYPE   USAGE         USAGE_ID       LINE        COL USAGE_CONTEXT_ID
------------------------------ -------------------------------- ------------------ ------------------------------ ------------- ----------- ---------- ---------- ---------- ----------------
T_ASSOCIATIVE                  9A18FE6BCB72110F39CED9E08B932ECB ASSOCIATIVE ARRAY  MY_TYPES                       PACKAGE       DECLARATION          4          4          8                1
T_TABLE_TYPE                   77067FE9732B492C166D38221DC3DF37 NESTED TABLE       MY_TYPES                       PACKAGE       DECLARATION          3          3          8                1
T_CURSOR_TYPE                  EDEC9260784B7721BC3F3DAB293F23DD REFCURSOR          MY_TYPES                       PACKAGE       DECLARATION          2          2          8                1

zep@dev> 

答案 1 :(得分:1)

编辑:从Zep找到的文档中,语句仅适用于11.1之前的oracle版本

对你来说是坏消息:

这些类型仅在执行包时存在,因此永远不会在oracle词典中看到它们。换句话说,这些类型不是 in 数据库,而是它们在包中。

适合您的好消息:

包在数据字典中,所以我们可以运行一些sql来搜索包含你关心的关键字的程序和包;在这个例子中'TYPE':

SELECT *
FROM dba_source
WHERE type IN ('PROCEDURE','PACKAGE','PACKAGE BODY')
AND text LIKE '%TYPE%IS%';

从那里定义您关心的所有者,并使用一些正则表达式或其他花哨的代码来提取您需要的数据。

或者,如果要查看数据字典中的类型,则必须在包外部创建它们,然后从包中引用该类型。

参考文献:

Oracle® Database Reference 11g Release 1 (11.1) - ALL_TYPES

答案 2 :(得分:1)

无需任何特殊编译标志的复杂解决方案

这是我为版本3.9中的jOOQ代码生成器设计的解决方案,用于发现PL / SQL RECORD类型。它只发现实际引用的那些类型:

SELECT x.type_owner, x.type_name, x.type_subname, a.*
FROM all_arguments a
JOIN (
  SELECT 
    type_owner, type_name, type_subname,
    MIN(owner        ) KEEP (DENSE_RANK FIRST ORDER BY owner, package_name, subprogram_id, sequence) owner,
    MIN(package_name ) KEEP (DENSE_RANK FIRST ORDER BY owner, package_name, subprogram_id, sequence) package_name,
    MIN(subprogram_id) KEEP (DENSE_RANK FIRST ORDER BY owner, package_name, subprogram_id, sequence) subprogram_id,
    MIN(sequence     ) KEEP (DENSE_RANK FIRST ORDER BY owner, package_name, subprogram_id, sequence) sequence,
    MIN(next_sibling ) KEEP (DENSE_RANK FIRST ORDER BY owner, package_name, subprogram_id, sequence) next_sibling,
    MIN(data_level   ) KEEP (DENSE_RANK FIRST ORDER BY owner, package_name, subprogram_id, sequence) data_level
  FROM (
    SELECT 
      LEAD(sequence, 1, sequence) OVER (
        PARTITION BY owner, package_name, subprogram_id, data_level 
        ORDER BY sequence
      ) next_sibling,
      a.type_owner,
      a.type_name, 
      a.type_subname,
      a.owner,
      a.package_name,
      a.subprogram_id,
      a.sequence,
      a.data_level,
      a.data_type
    FROM all_arguments a
  ) a
  WHERE data_type = 'PL/SQL RECORD'
  GROUP BY type_owner, type_name, type_subname
) x
ON (a.owner, a.package_name, a.subprogram_id) 
= ((x.owner, x.package_name, x.subprogram_id))
AND a.sequence BETWEEN x.sequence AND x.next_sibling
AND a.data_level = x.data_level + 1
ORDER BY x.type_owner, x.type_name, x.type_subname, a.sequence
;

More details about the above technique can be found here

相对容易(但不完整)的解决方案依赖于特殊的编译标志

我刚发现this extremely interesting website,其中列出了使用字典视图mentioned in zep's answer here的查询。使用问题中的包,使用此查询:

WITH plscope_hierarchy
        AS (SELECT line
                 , col
                 , name
                 , TYPE
                 , usage
                 , usage_id
                 , usage_context_id
              FROM all_identifiers
             WHERE     owner = USER
                   AND object_name = 'MY_TYPES'
                   AND object_type = 'PACKAGE')
SELECT    LPAD (' ', 3 * (LEVEL - 1))
       || TYPE
       || ' '
       || name
       || ' ('
       || usage
       || ')'
          identifier_hierarchy
  FROM plscope_hierarchy
START WITH usage_context_id = 0
CONNECT BY PRIOR usage_id = usage_context_id
ORDER SIBLINGS BY line, col;

产生这个结果

PACKAGE MY_TYPES (DECLARATION)
   REFCURSOR T_CURSOR_TYPE (DECLARATION)
   NESTED TABLE T_TABLE_TYPE (DECLARATION)

不幸的是,嵌套表类型不再被解析。

答案 3 :(得分:0)

它不会从all_typesall_objects提供,但作为替代方案,您可以向user_source查询该类型的名称,它应该显示出来。

答案 4 :(得分:-1)

尝试使用collection作为包函数/procedurę的参数,然后查看字典 user_arguments

select *
  from user_arguments a
 where a.object_name = 'MYFUNCTIONNAME'
 order by a.sequence;