5

考虑到我有一个名为 SBST 的模式

我想在这个 SBST Schema 中找到所有空表列表。是否有任何 PL/SQL 程序可以找到它。我发现很少。但是那些正在使用我无法指定模式名称 SBST 的用户表。

我正在使用这个

select table_name from dba_tables where owner ='SBST'
having count(*)=0  group by table_name

上面的查询有什么问题?

4

4 回答 4

8

类似于@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;
/

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


具体来说,您的查询出了什么问题……您的havingandgroup by子句使用了错误的方法;但无论如何它总是不会返回任何数据,因为如果 SBST 有任何表,那么它count (*) from dba_tables必须是非零的,所以having总是匹配;如果没有,那么,无论如何都没有数据,所以没有什么having可以匹配的。您正在计算有多少表,而不是每个表中有多少行。

于 2012-06-21T11:13:50.907 回答
8

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

select * from ALL_TABLES 
where owner ='SBST'
AND NUM_ROWS = 0;
于 2015-08-19T12:23:51.367 回答
4

直截了当的答案是

select 'select ''' || table_name || ''' from ' || table_name || ' 
    having count(*) = 0;' from dba_tables where owner='SBST';

解释

你可以运行这个......它只会输出那些没有行的表名:假设你使用 sqlplus 但我用 toad 来测试它,它工作得很好 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 user_tables where owner='SBST';
spool off;

@tmp.sql 

如果你打开“tmp.sql”文件,你会看到所有的表......

select 'PERSONS' from PERSONS having count(*) = 0;
select 'DEPARTMENT' from DEPARTMENT having count(*)=0; 

在您的情况下,如果您与用户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 


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

我的结果图片上传

**概括 **

请运行此查询

select 'select ''' || table_name || ''' from ' || table_name || ' 
    having count(*) = 0;' from dba_tables where owner='SBST';
于 2012-06-21T09:20:15.107 回答
1

如果表统计信息是最新的,那么您可以使用:

SELECT TABLE_NAME
FROM ALL_TAB_STATISTICS
WHERE (OWNER = 'ME')
  AND (NUM_ROWS = 0);
于 2016-06-03T08:20:11.220 回答