【问题标题】:Get counts of all tables in a schema获取模式中所有表的计数
【发布时间】:2012-05-29 02:35:29
【问题描述】:

我正在尝试获取架构中所有表的记录数。我在编写 PL/SQL 时遇到问题。这是我到目前为止所做的,但我遇到了错误。请提出任何更改:

DECLARE
v_owner varchar2(40);
v_table_name varchar2(40);

cursor get_tables is
select distinct table_name,user
from user_tables
where lower(user) = 'SCHEMA_NAME';


begin

open get_tables;
fetch get_tables into v_table_name,v_owner;

    INSERT INTO STATS_TABLE(TABLE_NAME,SCHEMA_NAME,RECORD_COUNT,CREATED)
    SELECT v_table_name,v_owner,COUNT(*),TO_DATE(SYSDATE,'DD-MON-YY') FROM         v_table_name;

CLOSE get_tables;

END;

【问题讨论】:

  • 如果您发布您的错误而不是试图让我们猜测会很有帮助。幸运的是,您制作了几款经典的灯笼裤,所以这次很容易。

标签: oracle plsql


【解决方案1】:

这可以通过一条语句和一些 XML 魔法来完成:

select table_name, 
       to_number(extractvalue(xmltype(dbms_xmlgen.getxml('select count(*) c from '||owner||'.'||table_name)),'/ROWSET/ROW/C')) as count
from all_tables
where owner = 'FOOBAR'

【讨论】:

  • 完美答案。谢谢你:)
  • 请注意,某些 table_name 可能区分大小写,因此如果您不将其括在双引号中,则内部查询可能会失败,即 'select count(1) c from '||owner||'."'||table_name ||'"'
  • 可爱的东西。这是唯一适用于 Oracle 9 的解决方案。
【解决方案2】:

应该这样做:

declare
    v_count integer;
begin

    for r in (select table_name, owner from all_tables
              where owner = 'SCHEMA_NAME') 
    loop
        execute immediate 'select count(*) from ' || r.table_name 
            into v_count;
        INSERT INTO STATS_TABLE(TABLE_NAME,SCHEMA_NAME,RECORD_COUNT,CREATED)
        VALUES (r.table_name,r.owner,v_count,SYSDATE);
    end loop;

end;

我从您的代码中删除了各种错误。

注意:为了其他读者的利益,Oracle 不提供名为STATS_TABLE 的表,您需要创建它。

【讨论】:

  • 小错字:INSERT 值中的 l_count 应该是 v_count
  • 建议几个变体...我最近开始喜欢构造要在隐式游标的 selet 子句中执行的 SQL,因为它允许您运行 select 并查看语句是什么生成。也可以将插入语句构造为动态 SQL,并将插入和选择组合成一个操作。只有几个选择...
  • ORA-06550:第 10 行,第 21 列:PL/SQL:ORA-00942:表或视图不存在 ORA-06550:第 10 行,第 9 列:PL/SQL:忽略 SQL 语句
  • 我在这里遇到了与@SherlockSpreadsheets 相同的错误。
  • @Benjamin 也许您没有像 OP 那样的名为 STATS_TABLE 的表?这将是您自己创建的表。
【解决方案3】:
select owner, table_name, num_rows, sample_size, last_analyzed from all_tables;

这是检索行数的最快方法,但有一些重要的注意事项:

  1. 如果在 11g 及更高版本中使用 ESTIMATE_PERCENT => DBMS_STATS.AUTO_SAMPLE_SIZE(默认值)或在早期版本中使用 ESTIMATE_PERCENT => 100 收集统计信息,NUM_ROWS 仅 100% 准确。请参阅this post 了解如何 AUTO_SAMPLE_SIZE 算法适用于 11g。
  2. LAST_ANALYZED 开始生成结果,当前结果可能不同。

【讨论】:

    【解决方案4】:

    如果您想要 Oracle 的简单 SQL(例如,没有 XmlGen 的 XE),请选择简单的两步:

    select ('(SELECT ''' || table_name || ''' as Tablename,COUNT(*) FROM "' || table_name || '") UNION') from USER_TABLES;
    

    复制整个结果并将最后一个 UNION 替换为分号 (';')。然后作为第二步执行生成的 SQL。

    【讨论】:

    • 如果有很多表我认为复制结果很耗时。
    【解决方案5】:

    获取模式中所有表的计数并按 desc 排序

    select 'with tmp(table_name, row_number) as (' from dual 
    union all 
    select 'select '''||table_name||''',count(*) from '||table_name||' union  ' from USER_TABLES 
    union all
    select 'select '''',0 from dual) select table_name,row_number from tmp order by row_number desc ;' from dual;
    

    复制整个结果并执行

    【讨论】:

      【解决方案6】:

      你必须使用立即执行(动态 sql)。

      DECLARE 
      v_owner varchar2(40); 
      v_table_name varchar2(40); 
      cursor get_tables is 
      select distinct table_name,user 
      from user_tables 
      where lower(user) = 'schema_name'; 
      begin 
      open get_tables; 
      loop
          fetch get_tables into v_table_name,v_owner; 
          EXIT WHEN get_tables%NOTFOUND;
          execute immediate 'INSERT INTO STATS_TABLE(TABLE_NAME,SCHEMA_NAME,RECORD_COUNT,CREATED) 
          SELECT ''' || v_table_name || ''' , ''' || v_owner ||''',COUNT(*),TO_DATE(SYSDATE,''DD-MON-YY'')     FROM ' || v_table_name; 
      end loop;
      CLOSE get_tables; 
      END; 
      

      【讨论】:

        猜你喜欢
        • 2019-02-17
        • 1970-01-01
        • 2022-08-12
        • 2018-09-05
        • 2011-04-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多