从软件包文件中提取软件包名称和注释

时间:2019-04-09 18:49:38

标签: sql oracle plsql

我需要从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行。

3 个答案:

答案 0 :(得分:3)

我将从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 :(得分:1)

或者,您可以创建一个日志表

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; 

答案 2 :(得分:0)

大多数关于包装规格和包装体的描述都在'/ *'或'-'符号后面,并且没有标准要求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 
                        */