暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle 如何提取PL/SQL源代码差异忽略注释、空格、换行符等

askTom 2018-01-10
842

问题描述

嗨: 我需要比较两个数据库 (例如,Homo和Prod) 之间的所有PL/SQL源代码 (即过程,函数,包和触发器),以获取差异。
重点是,我想只获得功能差异,即,只有有意义的源代码差异,丢弃由换行符,大写/小写,注释等引起的差异。因此,两个源代码摘录belowe都必须被认为是不不同的:

=> PROD数据库中的源代码

....
-在PROD @ 2017/12/31中输入的查询
选择可乐,
colB,来自mytable的colC
其中colA = 2;

==> HOMO数据库中的源代码

....
-查询中
-同性恋 @ 2017/12/10
--
选择可乐, colB, colC FROM mytable where COLA=2;
/*
然而
另一个
评论...
*/

我当时正在考虑通过字符串函数删除注释/换行符/空格,但是我无法烹饪一些东西...只是补充一下,有些源代码很小,但有些可能很大...

问候,

J.劳林多·基亚帕

专家解答

您可以使用一些PLSQL清理数据。之后,您可以将其假脱机到文件中并使用普通的比较工具 (diff等),也可以将其存储为clob并使用dbms_lob等。这是让你前进的东西

SQL> create or replace
  2  procedure scott.my_proc(
  3      p_string  in varchar2 default null,
  4      tag     in varchar2 default null,
  5      p_debug   in varchar2 default 'NO',
  6      p_trace   in varchar2 default 'NO',
  7      p_session in varchar2 default null)
  8  is
  9    b int := dbms_utility.get_time;
 10    l_question_id int;
 11  begin
 12  /*
 13    some multiline comments
 14     that end in the middle */ null;
 15    if tag is null then
 16      wwv_flow.show (
 17          p_flow_id      => '100',
 18          p_flow_step_id => '1',
 19          p_debug        => p_debug,   -- some stuff
 20          p_arg_names    => wwv_flow_utilities.string_to_table2('P1_SEARCH_CRITERIA'),
 21          p_arg_values   => wwv_flow_utilities.string_to_table2(p_string),
 22          p_instance     => p_session,
 23           -- some more stuff
 24          p_trace        => p_trace
 25      );
 26      htp.p(''||to_char((dbms_utility.get_time - b) * .01,'999,990.000')||'');
 27    end if;
 28    /* last little bit */
 29  end;
 30  /

Procedure created.

SQL>
SQL>
SQL> variable c clob
SQL> declare
  2    l_in_comment boolean default FALSE;
  3    l_comment_pos     int;
  4    l_text            varchar2(4000);
  5  begin
  6    dbms_lob.createtemporary(:c,true);
  7    for i in ( select text
  8               from   dba_source
  9               where  owner = 'SCOTT'
 10               and    name  = 'MY_PROC'
 11               and    type  = 'PROCEDURE'
 12               order by line
 13             )
 14    loop
 15       -- santise case
 16       l_text := lower(i.text);
 17
 18       -- repeated spaces becomes single space
 19       while l_text like '%  %'
 20       loop
 21         l_text := replace(l_text,'  ',' ');
 22       end loop;
 23
 24       -- single line comments removed
 25       l_comment_pos := instr(l_text,'--');
 26       if l_comment_pos > 1 then
 27         l_text := substr(l_text,1,l_comment_pos-1);
 28       elsif l_comment_pos > 0 then
 29         l_text := null;
 30       end if;
 31
 32
 33       -- multi line comments
 34       l_comment_pos := instr(l_text,'/*');
 35       if l_comment_pos > 0 then
 36          l_in_comment := true;
 37          if l_comment_pos > 1 then
 38            l_text := substr(l_text,1,l_comment_pos-1);
 39          else
 40            l_text := null;
 41          end if;
 42       end if;
 43
 44       l_comment_pos := instr(l_text,'*/');
 45       if l_in_comment then
 46         if l_comment_pos > 0 then
 47            l_text := substr(l_text,l_comment_pos+3);
 48            l_in_comment := false;
 49         else
 50            l_text := null;
 51         end if;
 52       end if;
 53
 54  --     l_text := replace(replace(l_text,chr(10)),chr(13));
 55       if l_text is not null then
 56         dbms_lob.writeappend(:c,length(l_text),l_text);
 57       end if;
 58    end loop;
 59  end;
 60  /

PL/SQL procedure successfully completed.

SQL>
SQL>
SQL> print c

C
--------------------------------------------------------------------------------
procedure my_proc(
 p_string in varchar2 default null,
 tag in varchar2 default null,
 p_debug in varchar2 default 'no',
 p_trace in varchar2 default 'no',
 p_session in varchar2 default null)
is
 b int := dbms_utility.get_time;
 l_question_id int;
begin
null;
 if tag is null then
 wwv_flow.show (
 p_flow_id => '100',
 p_flow_step_id => '1',
 p_debug => p_debug,  p_arg_names => wwv_flow_utilities.string_to_table2('p1_sea
rch_criteria'),
 p_arg_values => wwv_flow_utilities.string_to_table2(p_string),
 p_instance => p_session,
  p_trace => p_trace
 );
 htp.p(''||to_char((dbms_utility.get_time - b) * .01,'999,990.000'
)||'');
 end if;


SQL>


如果您在第54行中返回评论,您也将删除回车单
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论