Oracle搜索字符串中的单词列表并重新编译现有单词

时间:2018-03-07 17:03:28

标签: oracle

我正在尝试编写有关所使用的数据仓库表的统计信息。

因此我应该进行查询以使用过的表格。

我有一个表名列表,我有一个数据库表,其中存储了查询。

如何选择包含在?

中使用的表名的行
Report Table:
...
QUERYTEXT String
...


select * from Report where QUERETEXT (?)

DWTableNames: DWA, DWB,..

我想使用querytext字段中存在的数据仓库表名打印每个报告。

2 个答案:

答案 0 :(得分:0)

以下是我搜索的解决方案:

WITH dwtables(dwtable) AS (
  SELECT 'DWA' FROM dual UNION ALL
  SELECT 'DWB' FROM dual UNION ALL
  SELECT 'DWC' FROM dual

)--> Tabelle mit einem Spalte (Liste)

SELECT title, 
    (SELECT LISTAGG (dwtable, ', ' ) WITHIN GROUP (ORDER BY dwtable)
     FROM dwtables
    WHERE REGEXP_LIKE (r.querytext, '(^|\s)'||dwtables.dwtable||'(\s|$)', 'i')) AS dwtables

 FROM Reports r;

答案 1 :(得分:0)

从SQL查询列表中提取表名称的简单方法

<强>设置 我们假设这是您的查询列表:

select * from a where id = 1;
select * from v;
with my_id as (select id from b)
select  /*+ PARALLEL(4) */ * from a where id in (select id from my_id);

为了覆盖视图访问,这里是表定义:

create table a (id number);
create index a_idx  on a(id);

create table b (id number);
create table c (id number);
create table d (id number);

create view v as
select c.id from c join d on c.id = d.id;

因此a, b, c and d

上有vc and d表格

*因此,您希望查看表a, b, c and d的列表,即使在查询列表中,也只能直接引用表a, b

<强>解决方案

第一步中将您的查询列表转换为EXPLAIN PLAN语句列表。如果列表具有非平凡的长度,您可能会发现使用某种脚本是切实可行的:

EXPLAIN PLAN  SET STATEMENT_ID = 'q1' into   plan_table  FOR select * from a where id = 1;
EXPLAIN PLAN  SET STATEMENT_ID = 'q2' into   plan_table  FOR select * from v; 
EXPLAIN PLAN  SET STATEMENT_ID = 'q3' into   plan_table  FOR with my_id as (select id from b)
select  /*+ PARALLEL(4) */ * from a where id in (select id from my_id);

通过执行EXPLAIN PLAN语句,plan_table填充了执行计划,每个操作的访问对象都存储在OBJECT_OWNER, OBJECT_NAME列中。

第一个天真查询返回此列表:

select distinct  OBJECT_OWNER,  OBJECT_NAME  
from plan_table 
where statement_id in ('q1','q2','q3') and OBJECT_NAME is not NULL
order by 1,2;

OBJECT_OWNER OBJECT_NAME
------------ -----------
DWH          A_IDX       
DWH          B           
DWH          C           
DWH          D           
SYS          :TQ10000    
SYS          :TQ10001    
SYS          :TQ10002 

必须修复两件事。 首先,必须忽略并行执行的行源(例如:TQ10000),因为它们不是真正的表。 其次,索引名称(例如A_IDX)必须使用字典视图DBA_INDEXES映射到table_names。

请注意,您无需特别注意视图,因为它们会自动解析为源表。 子查询因子分析with子句)也是如此。

接近这两个主题的查询如下所示:

select distinct OBJECT_OWNER, 
/* map index name to table name */
case when p.OPERATION = 'INDEX' then i.TABLE_NAME else p.OBJECT_NAME end as TABLE_NAME  
from plan_table p
left outer join dba_indexes i on p.OBJECT_OWNER = i.OWNER and p.OBJECT_NAME = i.INDEX_NAME
where statement_id in ('q1','q2','q3') and OBJECT_NAME is not NULL
and p.OBJECT_NAME not like ':%' /* suppress parallel row sources */
order by 1,2;

OBJECT_OWNER TABLE_NAME
------------ ----------
DWH          A          
DWH          B          
DWH          C          
DWH          D 

最后请注意,此方法仅在所有查询和视图在语法上都有效且您的用户具有足够的权限来解释列表中所有查询的计划时才有效。