【问题标题】:Oracle Dynamic Query for all tables所有表的 Oracle 动态查询
【发布时间】:2021-04-15 20:36:36
【问题描述】:

我有两个疑问, 第一个获取表名和avg_row_len

select Table_name, AVG_ROW_LEN  from all_tables
where Table_name = 'COMPU_ERROR_FACT';

然后我需要将 avg_row_len 传递给

SELECT  COUNT(1) as "Number of Count", 
        ROUND(COUNT(1) * avg_row_len/1024/1024) AS "Size in MB" , 
        TO_CHAR(CREATE_DATE, 'YYYY') AS YEAR,
        'CREATE_DATE' AS DATTT
FROM COMPU_ERROR_FACT --table name
GROUP BY  TO_CHAR(CREATE_DATE, 'YYYY')
order by 3;

我有超过 2k 个表,有没有办法一次性获取所有表的详细信息。

请推荐,

【问题讨论】:

  • 您是否需要将其作为单个查询(您的问题暗示了这一点)?您可以使用 XMLQuery 做一些事情,但这往往是相当深奥的。或者您可以使用一些 PL/SQL,例如,将数据写入您稍后查询的表(您的标签暗示)?
  • 好吧,除非这 2K 个表中的每一个都包含 CREATE_DATE 列,否则这会以某种方式失败。是吗?
  • 是的,它们都有 Create_date
  • 您想获取表格的大小吗?如果是,那么查看ALL_SEGMENTS 可能会更好。

标签: oracle plsql


【解决方案1】:

不确定您是否只需要查询或 PLSQL 块。

因此,如果您需要查询,可以使用以下 PLSQL 代码构建它。运行它并从输出中运行巨大的 sql。不要忘记删除尾随的“union all”

begin
  for t in (select * from all_tables) loop
    dbms_output.put_line('select count(1) "number of count", ROUND(COUNT(1) * avg_row_len/1024/1024) "Size in MB", TO_CHAR(CREATE_DATE, ''YYYY'') AS YEAR, ''CREATE_DATE'' AS DATTT
                        FROM t.table_name 
                       GROUP BY  TO_CHAR(CREATE_DATE, ''YYYY'')
                      order by 3');
     dbms_output.put_line('union all');
  end loop;
end;

如果 PLSQL 是可以接受的,你可以使用这个

declare
  cnt number;
  avg_len number;
  create_year varchar2(4);
  dattt varchar(10); -- in youe example it will get constatly populated with 'CREATE_DATE', check if you need it at all
begin
  for t in (select * from all_tables) loop
    execute immediate 'select count(1) "number of count", ROUND(COUNT(1) *     avg_row_len/1024/1024) "Size in MB", TO_CHAR(CREATE_DATE, ''YYYY'') AS YEAR,     ''CREATE_DATE'' AS DATTT
                        FROM ' ||t.owner || '.' || t.table_name ||
                       ' GROUP BY  TO_CHAR(CREATE_DATE, ''YYYY'')
                      order by 3'
    into cnt, avg_len, create_year, dattt;                          
    -- do something with data you've just selected
  end loop;
end;

请注意 all_tables 包含您可以访问的所有表的名称。所以会有系统表和来自其他模式的表。这就是我添加“t.owner”的原因。

也许您需要 user_tables 视图,其中仅包含您的用户创建的对象的名称。检查使用“user_tables”系统视图是否会在这里做得更好。

仅供参考:可以从 dba_segments 表中获取以 MB 为单位的表大小:

select bytes / 1024 / 1024 from dba_segments where segment_name = 'TABLE_NAME'

【讨论】:

  • 如何从输出中运行庞大的 sql?
  • @author4 将其复制到剪贴板并粘贴到您运行 SQL 的位置
  • ... 并删除尾随 UNION ALL;)
猜你喜欢
  • 2021-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多