Извлечение имени пакета и комментариев из файлов пакета - PullRequest
2 голосов
/ 09 апреля 2019

Мне нужно получить имя пакета и первые строки комментариев из файла пакета PL / SQL (спецификация и / или тело) или из пакета, скомпилированного в BD.

Я знаю, что существует скрипт для получения имени пакета, но ему нужно получить описание из пакета.

Например, если мне нужно получить имена пакетов, я могу выполнить этот выбор:

select * from all_objects where object_name like 'pack%';

Но если мне нужно получить результат запроса плюс имя пакета, первые строки из пакета. Если пакет начинается с:

CREATE OR REPLACE PACKAGE BODY pack_test AS
/* **************************************************** */
*  Description: maintenance package from suppliers table *
*  Author:  reymagnus                                    *
*  Creation date: 09/04/2019                             *
*  (another comments)                                    *
*  **************************************************** */

Я ожидаю получить это:

Object_Type   Object_Name  Description
===========   ===========  ===========   
PACKAGE       pack_test    maintenance package from suppliers table

или

Object_Type   Object_Name  Description_line
===========   ===========  ================ 
PACKAGE       pack_test    CREATE OR REPLACE PACKAGE BODY pack_test AS
PACKAGE       pack_test    /* **************************************************** */
PACKAGE       pack_test    *  Description: maintenance package from suppliers table *

Может быть, мне нужно присоединиться к таблице all_objects и all_source и получить только <= 3 строки. </p>

Ответы [ 3 ]

3 голосов
/ 09 апреля 2019

Я бы получил имя пакета от all_objects, потому что оно все равно есть.

Парсинг комментария должен быть выполнимым. Просто найдите строку, которая начинается с * Description:, и возьмите оставшуюся часть этой строки.

REGEXP_SUBSTR может быть хорошей функцией для анализа или некоторых базовых строковых функций, таких как:

select
  o.OWNER,
  o.OBJECT_NAME,
  ( select
      MIN(TRIM(SUBSTR(s.TEXT, INSTR(s.TEXT, 'Description:') + 12)))
    from 
      ALL_SOURCE s 
    where
      s.NAME = o.OBJECT_NAME
      and s.OWNER = o.OWNER
      and s.LINE <= 5
      and s.TEXT like '% Description:%') as DESCRIPTION
from
  ALL_OBJECTS o
where
  o.OBJECT_TYPE = 'PACKAGE';

Следует отметить, что эта проверка немного грубовата. Теоретически текст Description: также может быть частью некоторого кода или запроса, поэтому теоретически вы можете получить ложное срабатывание и получить странное описание.

Кроме того, эта проверка довольно строгая. Если вы ввели description (строчные буквы) или description : (пробел перед двоеточием) или *Description: (пробел между звездочкой и словом отсутствует), совпадения не будет.

Кроме того, я использовал MIN для получения любых описаний на случай, если их несколько. Лично я думаю, что хорошо ловить крайние случаи как это. Вы также можете использовать LIST_AGG, чтобы вернуть все из них, что дает большое преимущество, позволяя использовать многострочные описания ...:)

1 голос
/ 10 апреля 2019

Кроме того, вы можете создать таблицу регистрации

create table t_log( obj_name varchar2(35), obj_type varchar2(35), obj_rows varchar2(4000) );

и заполнить ее, используя user_source представление словаря и ограничив его тремя строками

declare
  v_plsql_unit varchar2(35):= 'my_package';
begin
  for c in ( select * from user_source s where s.name = upper(v_plsql_unit) order by s.line )
  loop
   begin 
      insert into t_log values( c.name, c.type, c.text );
    exit when c.line = 3;
   end;  
    commit;
  end loop;
end; 
0 голосов
/ 10 апреля 2019

описания спецификации пакета и тела пакета в основном следуют за символами '/ *' или '-', и нет никаких критериев, что ключевое слово description должно быть там, если это не бизнес-критерии. если это критерий, то можно использовать ключевое слово, в противном случае приведенный ниже запрос может быть отослан и изменен в соответствии с потребностями.

-- package to query: sample_pkg
select o.owner, 
       o.object_name,
      (select listagg(a.text ) WITHIN GROUP (ORDER BY a.line asc)  
       from all_source a 
       where a.name =o.object_name
         and a.line between (select b.line from all_source b where b.name=a.name and b.text like '%'||chr(47)||'*%')
                        and (select c.line from all_source c where c.name =a.name and c.text like '%*'||chr(47)||'%')
            ) description
from all_objects o 
where o.object_type like 'PACK%' 
and o.object_name like 'SAMP%';

-- output
OWNER       OBJECT_NAME DESCRIPTION
SQL_user    SAMPLE_PKG  /* 
                        sample spec description 
                        */ 

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...