我想写一个查询,返回一组表中的记录总数。我希望查询超过40个表,因此手动键入每个表将是一个大型繁琐的查询。在这种情况下,我希望包含在查询中的所有表都具有以'PERF_'开头的表名 那么我如何编写一些能够返回表名以特定字符串开头的所有表的行计数总和的东西?谢谢!
答案 0 :(得分:1)
这不是一个真正的“查询”,但您可以使用这样的PL / SQL实现您想要做的事情:
DECLARE
nbr NUMBER := 0;
total NUMBER := 0;
stmt VARCHAR2(100):= 'SELECT COUNT(*) FROM ';
BEGIN
-- Iterate over all tables that fit your criteria
FOR i IN (SELECT TABLE_NAME FROM ALL_TABLES t WHERE /*t.owner = '#####' and*/ t.table_NAME LIKE 'PERF_%') LOOP
nbr := 0;
EXECUTE IMMEDIATE stmt || i.TABLE_NAME INTO nbr;
total := total + nbr;
END LOOP;
dbms_output.put_line('total : '||total);
END;
如果您无权访问ALL_TABLES,请尝试USER_TABLES。
答案 1 :(得分:1)
在这种情况下,要创造性地懒惰。例如,您可以针对USER_TABLES
编写查询,输出是单行中的单个列,文本字符串是可以执行所需操作的SQL语句。
假设我在架构中创建了两个新表,一个包含8行,另一个包含4行,如下所示。
create table perf_1 as select level lvl from dual connect by level <= 8;
Table PERF_1 created.
create table perf_2 as select level lvl from dual connect by level <= 4;
Table PERF_2 created.
计算行的SQL:
select count(*) from
( select * from perf_1 union all select * from perf_2 )
;
COUNT(*)
----------
12
好的,但是如何编写一个输出为我刚刚使用的SELECT COUNT(*)...
语句的SQL?
像这样:
select
'select count(*) from
( '
|| listagg('select * from ' || table_name, ' union all ')
within group (order by table_name)
|| ' )
;' as sql_string
from user_tables
where table_name like 'PERF_%'
;
SQL_STRING
------------------------------------------------------------
select count(*) from
( select * from PERF_1 union all select * from PERF_2 )
;
(好吧,它不会产生完全相同的文本;表名将是大写的,但这是唯一的区别)
现在复制SQL_STRING并执行它。
注意:LISTAGG()
的限制为4000字节。这种方法适用于40个表,但可能不适用于400个表(对于每个表,即使忽略表名,我们每个表使用10个以上的字符)。