想知道某一个表是否在数据库的pl/sql代码中被使用了,有两种办法:
一种是通过数据库视图:user_dependencies查询,可以很清楚的知道哪个对象被依赖或哪个对象依赖哪些对象。但是,这个视图也有不足之处,它描述的是静态代码中依赖的对象,我称之为硬关联,这个编译时就得存在,否则会报错。因此,其依赖关系也就是在编译的时候就确定了。但是,如果要知道动态语句中涉及到的表等,这个视图就无法解决了,因为这个是在执行时才调用的对象,而不是在编译时就知道的。
于是,我写了一个sql,利用user_source这个视图,将源代码中含有相应对象的语句找出来,然后通过正则表达式将对象名称提取出来。其缺点是目前只支持单行出现一次的情况,如果出现两次,就无法正确匹配了。
sql如下:
with tmp as(select replace(lower('TMAILBILL_INVEST_LOCAL'),'_','\_') tt from dual)
select a.name, a.text,
regexp_substr(regexp_replace(lower(a.text),
'[^a-z|A-Z|_| |,|''|0-9]',--将非数字英文字符下划线逗号的字符替换为空格(主要是为了过滤中文)
' '
),
'[^ |,|.|''|(]*' || replace(b.tt,'\') || '[^ |,|''|)]*'--找出对象名
) full_table_name
from user_source a, tmp b
where lower(text) like '%' || b.tt || '%' escape '\'
and a.text not like '%--%';
这里有个非常有意思的现象,对escape的使用我之前不是很了解,以为是放在sql语句最后的一个指示器,用来指定转义符,但是发现一个我一开始认为是个bug的问题:
下面这个sql居然没有结果:
select * from (select ' aaaa_bbb' aa from dual) a
where a.aa like '%' || 'aaaa\_bbb' || '%'
and a.aa not like '%--%'
escape '\'
按理讲,a.aa not like '%--%'这个肯定是成立的,
a.aa like '%' || 'aaaa\_bbb' || '%'这个也是成立的,因为有escape指定的转义符进行转义,但是结果却是空的。
一开始没想明白,后来尝试将escape放到a.aa like '%' || 'aaaa\_bbb' || '%'这个语句后面:
select * from (select ' aaaa_bbb' aa from dual) a
where a.aa like '%' || 'aaaa\_bbb' || '%' escape '\'
and a.aa not like '%--%'
发现居然也是可以的。于是立即想到,这个子句的作用域是当前条件,而不是整个where子句。所以放到最后的时候,其实是对a.aa not like '%--%'起作用的。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/12932950/viewspace-756611/ ,如需转载,请注明出处,否则将追究法律责任。