繁体   English   中英

如何从PL / SQL包主体文件中提取表名?

[英]How extract table names from PL/SQL package body file?

我需要在pl / sql软件包文件中查询表名称。

我知道regex在Notepad ++中为此提供了一个选项,但是我不知道要申请哪种正则表达式来获取表名(我知道必须是一些正则表达式才能使用关键字“ FROM”并在空格后获取下一个字符串, 我认同)。

对于下一个示例代码:

CREATE OR REPLACE PACKAGE BODY pac_example AS

FUNCTION f1 RETURN NUMBER IS
BEGIN
  SELECT * FROM table1;
  RETURN 1;
END f1;

FUNCTION f2 RETURN NUMBER IS
BEGIN
  SELECT * FROM table2;
  RETURN 1;
END f2;

END pac_example;

我希望全部替换并仅使用表名获取文件

table1
table2

如果您只对直接从PACKAGE BODY引用的表名感兴趣,则一种简单而直接的方法是查询all_dependenciesuser_dependencies

SELECT owner,
       referenced_name as table_name
FROM all_dependencies
WHERE type IN (
     'PACKAGE BODY'
) AND name IN (
     'PAC_EXAMPLE'
) AND referenced_type = 'TABLE';

演示

据我所知,没有人能做到100%准确。 您获得的最接近的是ALL / DBA_DEPENDENIES,但是不会告诉您是否在SELECT,INSERT,UPDATE或DELETE中访问了表。

但是它将解析同义词。

这样做的缺点是它将不包括动态SQL中引用的表。

如果您的数据库对表使用特定的命名约定(例如Tnnn_XXXXX),则可以执行以下操作:

SELECT DISTINCT c.text, c.name, c.type, t.table_name
FROM user_source c, user_tables t
WHERE UPPER(t.text) like '%' || t.name_name || '%' -- Maybe REGEXP_LIKE better
ORDER BY 2, 1, 4;

几十年前,我从事一个项目,他们想要一个CRUD程序矩阵(PLSQL,SQL,Oracle Forms / Reports,Pro C,Pro COBOL)以及每个表访问什么。

当时唯一可用的解决方案是我编写一个解析器(用C语言编写),该解析器对代码库进行解析以查找SQL并对其进行处理。 我什至报告了列和表格。 C程序分析了源代码,寻找关键字和字符来控制状态引擎。 优化和使用所有不同的代码库类型花了两个星期的时间。

最后,它唯一不能做的就是动态查询,其中表名是根据变量值构建的。 但是,此处的解决方法是捕获tkprof文件并对其进行处理。

可悲的是,我没有这个的源代码了。

但是,如果我要再做一次,我将使用Lex / Yacc / Bison解析SQL并围绕这些工具构建系统。

快速搜索发现:

https://github.com/jgarzik/sqlfun

https://www.oreilly.com/library/view/flex-bison/9780596805418/ch04.html

一项不小的任务。

  • Ctrl + H
  • 查找内容: (?:\\A(?:(?!FROM).)*|\\G)FROM\\s+(\\w+(?:\\s*,\\s*\\w+)*)(?:(?!FROM).)*
  • 替换为: " #a空格和双引号
  • 检查环绕
  • 检查正则表达式
  • 检查. matches newline . matches newline
  • 全部替换

说明:

(?:                 # start non capture group
  \A                # beginning of file
  (?:(?!FROM).)*    # Tempered greedy token, make sure we haven't FROM before
 |                  # OR
  \G                # restart from last match position
)                   # end group
FROM\s+             # literally FROM followed by 1 or more spaces
(                   # start group 1
  \w+               # 1 or more word characters (table name)
  (?:\s*,\s*\w+)*   # non capture group spaces comma spaces and 1 or more word characters, optional more tables
)                   # end group
(?:(?!FROM).)*      # Tempered greedy token, make sure we haven't FROM 

替代:

$1          # content of group 1, table name

屏幕截图:

在此处输入图片说明

您可以使用以下正则表达式搜索表名。

正则表达式: FROM\\s([^;]+)

替换: \\n%\\1%\\n

在此处输入图片说明

然后按照此答案替换文件中的其他数据。

前面提到的表

all_dependencies or user_dependencies 

可以列出前面提到的依赖项,但不会涵盖动态查询。 如果在记事本中使用“ from”之类的关键字进行搜索,则仅覆盖“ From”语句之后的语句所引用的表。

可以考虑使用以下代码段进行全面分析:-逐行,逐词并分析表格(请参阅您提到的示例)


declare
l_line varchar2(2000);
ln_start_string number;
ln_last_string number;
ln_string_length number;
l_word varchar2(4000);
l_table_flag varchar(2):='N';
cursor l_pkg_body_cur
is 
select TEXT from all_source where upper(name) like upper('pac_example') and type = 'PACKAGE BODY'; 
-- to get the source compiled in package boby, mentioned the package to be searched here
begin
for rec in l_pkg_body_cur
loop
-- line by line processing
select TRIM(rec.text) into l_line from dual;
ln_string_length := length(l_line);
loop
-- word by word processing
l_table_flag :='N';
select instr(l_line,' ') into ln_last_string from dual;
select substr(l_line,0,ln_last_string) into l_word from dual;
begin
select 'Y' into l_table_flag from all_tables where upper(table_name) like upper(trim(l_word)) and rownum=1; -- to validate it is table or not
exception
when others then
l_table_flag := 'N';
end;
IF l_table_flag = 'Y'
then
dbms_output.put_line(trim(l_word) ); -- table name
end if;
select length (l_word) into ln_start_string from dual;
select trim(substr(replace(l_line,';',null),ln_start_string)) into l_line from dual;
exit when l_line is NULL;
end loop;
end loop;
end;



--output:
Statement processed.
table1
table2

以类似的方式可以根据需要更改此查询,以查找所需的视图或同义词,方法是更改​​基表-all_views,all_synonyms。

这就像最简单的方法一样-可能需要更多的处理时间取决于包的大小,如果需要,可以直接使用UNIX脚本(也可以使用UTF_file操作)来使用UNIX脚本(如果需要直接从文件中进行检查)来​​完成相同的操作。从文件逐行进行并具有sql会话以执行上述验证并显示结果

希望这样可以提供最准确的结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM