查询以查找所有空表

use*_*625 5 oracle oracle11g

考虑到我有一个名为SBST的Schema

我想在此SBST Schema中找到所有空表列表.是否有任何PL/SQL过程可以找到它.我发现很少.但那些使用用户表,我无法指定Schema名称SBST.

我正在使用它

select table_name from dba_tables where owner ='SBST'
having count(*)=0  group by table_name
Run Code Online (Sandbox Code Playgroud)

上面的查询有什么问题?

小智 8

您可以在查询下面触发以查找没有数据的表列表

select * from ALL_TABLES 
where owner ='SBST'
AND NUM_ROWS = 0;
Run Code Online (Sandbox Code Playgroud)


Ale*_*ole 7

类似于@shareef的答案,但使用动态SQL来避免必须创建临时.sql文件.你需要dbms_output可见,例如set serveroutput on在SQL*Plus中 - 不知道Toad.

declare
    cursor c(p_schema varchar2) is
        select 'select ''' || table_name || ''' from ' ||
            p_schema ||'.' || table_name || ' where rownum < 2 ' ||
            ' having count(*) = 0' as query
        from all_tables
        where owner = p_schema
        order by table_name;
    l_table all_tables.table_name%TYPE;
begin
    for r in c('SBST') loop
        begin
            execute immediate r.query into l_table;
        exception
            when no_data_found then continue;
        end;

        dbms_output.put_line(l_table);
    end loop;
end;
/
Run Code Online (Sandbox Code Playgroud)

使用all_tables似乎比dba_tables这里更有用,所以你知道你可以从它列出的表中进行选择.我还在from子句中包含了模式,以防其他用户具有相同名称的表,因此如果您作为不同的用户连接,您仍然可以看到它 - 可能也避免同义词问题.


具体来说,你的查询有什么问题...你的条款havinggroup by条款是错误的; 但它总是不会返回任何数据,因为如果SBST有任何表,那么count (*) from dba_tables必须非零,所以having总是匹配; 如果没有那么,那么,无论如何都没有数据,所以没有任何东西having可以匹配.您计算的是有多少个表,而不是每个表中有多少行.


sha*_*eef 5

直接的答案是

select 'select ''' || table_name || ''' from ' || table_name || ' 
    having count(*) = 0;' from dba_tables where owner='SBST';
Run Code Online (Sandbox Code Playgroud)

解释

你可以运行这个...它只会输出那些没有行的表名:假设你使用sqlplus,但我用toad来测试它,它工作得很好设置回显关闭标题关闭反馈关闭行100页0;

spool tmp.sql
select 'select ''' || table_name || ''' from ' || table_name || ' 
having count(*) = 0;' from user_tables where owner='SBST';
spool off;

@tmp.sql 
Run Code Online (Sandbox Code Playgroud)

如果您打开“tmp.sql”文件,您将看到所有表......

select 'PERSONS' from PERSONS having count(*) = 0;
select 'DEPARTMENT' from DEPARTMENT having count(*)=0; 
Run Code Online (Sandbox Code Playgroud)

在您的情况下,您需要一个架构,并且架构是用户,如果您与用户SBST连接,则上面的代码是正确的,但如果您与其他用户连接,则必须使用DBA_TABLES并将所有者属性分配给SBST

USER_TABLES是您拥有的表ALL_TABLES是其他用户拥有的表以及其他用户拥有的表,您已被授予对这些表的显式访问权限DBA_TABLES是数据库中的所有表

像这样

set echo off heading off feedback off lines 100 pages 0;

spool tmp.sql
select 'select ''' || table_name || ''' from ' || table_name || ' 
having count(*) = 0;' from dba_tables where owner='SBST';
spool off;

@tmp.sql 
Run Code Online (Sandbox Code Playgroud)


所有三个都是底层 SYS 表的视图,但 USER_ 和 ALL_ 视图加入您的用户名/安全信息以限制结果

我的结果图片上传

**概括 **

请运行此查询

select 'select ''' || table_name || ''' from ' || table_name || ' 
    having count(*) = 0;' from dba_tables where owner='SBST';
Run Code Online (Sandbox Code Playgroud)