Обнаружение типов уровня пакета PL / SQL с использованием представлений словаря Oracle - PullRequest
6 голосов
/ 20 июня 2011

Могу ли я обнаружить типы, объявленные в пакетах 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_type и t_table_type.Кажется, они не перечислены в

SYS.ALL_TYPES

Под «формально» я подразумеваю, что мне нужны некоторые «формальные метаданные», то есть запрос USER_SOURCE не сработает.

Ответы [ 5 ]

6 голосов
/ 20 июня 2011

Только с 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 isинструмент, управляемый компилятором, который собирает данные об идентификаторах в исходном коде PL / SQL во время компиляции программного модуля и делает его доступным в словаре статических данных представления.Собранные данные включают информацию о типах идентификаторов, их использовании (объявление, определение, ссылка, вызов, назначение) и местонахождение каждого использования в исходном коде.

DEMO

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 голос
/ 15 декабря 2014

Комплексное решение, которое работает без каких-либо специальных флагов компиляции

Вот решение, которое я разработал для генератора кода jOOQ в версии 3.9 для обнаружения типов 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
;

Более подробную информацию о вышеупомянутой технике можно найти здесь .

Относительно простое (но неполное) решение, которое зависит от специального флага компиляции

Я только что открыл этот чрезвычайно интересный веб-сайт , который перечисляет запрос, использующий представления словаря , упомянутые в ответе zep здесь Используя пакет из вопроса, используйте этот запрос:

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)

К сожалению, тип вложенной таблицы больше не разрешается.

1 голос
/ 20 июня 2011

РЕДАКТИРОВАТЬ: Из документации, найденной Zep, заявление распространяется только на версии оракула до 11.1

Плохие новости для вас:

Эти типы существуют только при выполнении пакета, поэтому они никогда не будут видны в словаре оракула. Другими словами, эти типы не в базе данных, а в пакете.

Хорошая новинка для вас:

Пакет находится в словаре данных, поэтому мы можем запустить некоторые sql для поиска процедур и пакетов, которые содержат ключевые слова, которые вам интересны; в этом примере 'TYPE':

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

Оттуда определите владельца, о котором вы заботитесь, и введите регулярное выражение или другой причудливый код, чтобы получить нужные вам данные.

В качестве альтернативы, если вы хотите увидеть типы в словаре данных, вам придется создать их вне пакета, а затем ссылаться на этот тип из пакета.

Ссылки

Справочник по базе данных Oracle 11g, выпуск 1 (11.1) - ALL_TYPES

0 голосов
/ 17 декабря 2015

Попробуйте использовать коллекцию в качестве аргумента функции / процедуры пакета и затем посмотрите в словарь user_arguments :

select *
  from user_arguments a
 where a.object_name = 'MYFUNCTIONNAME'
 order by a.sequence;
0 голосов
/ 20 июня 2011

Оно не будет доступно из all_types или all_objects, но в качестве альтернативы вы можете запросить user_source для имени типа, и оно должно появиться.

...