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

2014-11-24 18:16:55 · 作者: · 浏览: 0

原理:


每个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;