【问题标题】:Extract package name and comments from package files从包文件中提取包名和注释
【发布时间】:2019-04-09 18:49:38
【问题描述】:

我需要从 PL/SQL 包文件(规范和/或正文)或从 BD 中编译的包中获取包名和 cmets 的第一行。

我知道有一个脚本来获取包名,但它需要从包中获取描述。

例如,如果我需要获取包名,我可以执行这个选择:

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

但是如果我需要在查询结果中加上包名,则从 package.json 开始。如果包以:

开头
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 表并且只得到

【问题讨论】:

  • 也许你会这样做(看起来是个好主意)。你试过了吗?
  • 关于作者和日期,我认为这样的东西不应该出现在包头中。毕竟,一段时间后会有修改,你会有多个作者和多个日期。而是将您的更改存储在版本控制中,因此您对源代码所做的每项更改都有作者+日期+提交消息/更改描述。

标签: sql oracle plsql


【解决方案1】:

我会从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 来返回所有这些,这具有允许多行描述的好处... :)

【讨论】:

    【解决方案2】:

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

    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; 
    

    【讨论】:

      【解决方案3】:

      package spec 和 package body 的描述大多在'/*' 或'--' 符号之后,并且没有规定必须有 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 
                              */ 
      
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-04-17
        • 2021-12-11
        • 2013-11-19
        • 2021-11-28
        • 2014-10-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多