我正在尝试编写有关所使用的数据仓库表的统计信息。
因此我应该进行查询以使用过的表格。
我有一个表名列表,我有一个数据库表,其中存储了查询。
如何选择包含在?
中使用的表名的行Report Table:
...
QUERYTEXT String
...
select * from Report where QUERETEXT (?)
DWTableNames: DWA, DWB,..
我想使用querytext字段中存在的数据仓库表名打印每个报告。
答案 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
v
和c 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
最后请注意,此方法仅在所有查询和视图在语法上都有效且您的用户具有足够的权限来解释列表中所有查询的计划时才有效。