复用Oracle数据字典解析出SQL语句中用到的所有表

原理:每个sql语句都它的执行计划,并且执行计划会放在plan_table中,plan_table中有object_name一列,该列表示sql语句中的对象名字,执行计划对表很感兴趣,所以如果object_type=’TABLE’,那么object_name就是我们要截取的table_name

执行步骤:

1、创建tmp_table 表,存放job名job_id,sql语句select_sql,和表名object_name

create table tmp_table(job_idvarchar2(50),select_sql clob,object_name varchar2(50));

模拟数据:

                                 A job中是一条比较短的sql语句        

    B job中是一条比较长的sql语句   

INSERTINTO TMP_TABLE VLAUES(‘A’,q’[A中的内容]’);

INSERTINTO TMP_TABLE VLAUES(‘B’,q’[B中的内容]’);

Commit;

2、创建p存储过程,根据执行计划

--以下是用4000以下的A job和4000 以上的B一起运行

create or replace procedure sqljiexiqi as

v_str  varchar2(4000);

v_sql  varchar2(4000);

v_sql1 varchar2(4000);

v_sql2 varchar2(4000);

v_sql3 varchar2(4000);

v_sql4 varchar2(4000);

v_sql5 varchar2(4000);

v_sql6 varchar2(4000);

v_sql7 varchar2(4000);

v_sql8 varchar2(4000);

v_sql9 varchar2(4000);

begin

dbms_output.enable(8000);

execute immediate 'truncate table tmp_table';

  forc in (select job_id, select_sql

              from bds.etl_job_info

            where length(trim(select_sql)) < 4000

               and job_id = 'A') loop

   v_sql := 'explain plan SET STATEMENT_ID=''' || c.job_id || ''' for ' ||

            c.select_sql;

   execute immediate v_sql;

   for re in (select distinct object_name

                 from plan_table

                where statement_id = c.job_id

                  and object_type = 'TABLE') loop

     insert into tmp_table

       (job_id, select_sql, object_name)

     values

       (c.job_id, c.select_sql, re.object_name);

   end loop;

   commit;

  endloop;

  forc in (select job_id, select_sql

              from bds.etl_job_info

            where length(trim(select_sql)) > =4000

               and job_id ='SJ_AS_CM_MORT_DTL_D') loop

   v_str  := 'explain plan SETSTATEMENT_ID=''' || c.job_id || ''' for ';

   v_sql  := substr(c.select_sql, 1,4000);

   v_sql1 := substr(c.select_sql, 1 * 4000 + 1, 4000);

   v_sql2 := substr(c.select_sql, 2 * 4000 + 1, 4000);

   v_sql3 := substr(c.select_sql, 3 * 4000 + 1, 4000);

   v_sql4 := substr(c.select_sql, 4 * 4000 + 1, 4000);

   v_sql5 := substr(c.select_sql, 5 * 4000 + 1, 4000);

    v_sql6:= substr(c.select_sql, 6 * 4000 + 1, 4000);

   v_sql7 := substr(c.select_sql, 7 * 4000 + 1, 4000);

   v_sql8 := substr(c.select_sql, 8 * 4000 + 1, 4000);

   v_sql9 := substr(c.select_sql, 9 * 4000 + 1, 4000);

   execute immediate v_str || v_sql || v_sql1 || v_sql2 || v_sql3 ||

                      v_sql4 || v_sql5 ||v_sql6 || v_sql7 || v_sql8 ||

                      v_sql9;

   for re in (select distinct object_name

                 from plan_table

                where statement_id = c.job_id

                  and object_type = 'TABLE')loop

     insert into tmp_table

       (job_id, select_sql, object_name)

     values

       (c.job_id, c.select_sql, re.object_name);

   end loop;

   commit;

  endloop;

end;

3、执行存储过程

   exec sqljiexiqi;

   

4、查询tmp_table表,得到sql中有哪些表

select * from tmp_table;

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/17013648/viewspace-752640/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/17013648/viewspace-752640/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值