Выбор всех таблиц без записей - PullRequest
5 голосов
/ 17 мая 2010

Мне нужно отобразить все таблицы с нулевыми записями.

Я пытался,

select * from user_all_tables where (select count(*) from user_all_tables)=0;

Но, похоже, это не работает. Как мне изменить дизайн этого запроса? Спасибо.

Ответы [ 5 ]

6 голосов
/ 17 мая 2010

Если проанализированы все ваши таблицы, вы можете проверить столбец num_rows таблицы user_tables.

В противном случае вам понадобится PL / SQL для этой работы. Это выведет все таблицы вашего текущего пользователя без записей (используйте all_tables, если вам нужны таблицы других пользователей):

Set Serveroutput On;

Declare
  cnt PLS_INTEGER;
Begin
  For c In ( Select table_name From user_tables ) Loop
    Execute Immediate 'Select Count(*) From "' || c.table_name || '" where rownum=1'
            Into cnt;
    If( cnt = 0 ) Then
      dbms_output.put_line( c.table_name );
    End If;
  End Loop;
End;
3 голосов
/ 17 мая 2010

Вам придется прибегнуть к PL / SQL и выдать счетчик выбора (*) для каждой таблицы. Или вы можете использовать dbms_xmlgen, чтобы сделать это для вас хитрым способом:

select table_name
  from ( select table_name
              , extractvalue
                ( dbms_xmlgen.getxmltype('select count(*) c from '|| table_name)
                , '/ROWSET/ROW/C'
                ) cnt
              , rownum to_prevent_predicate_push
           from user_tables
       )
 where cnt = '0'

С уважением, Роб.

2 голосов
/ 17 мая 2010

Изменение принятого ответа, но с использованием более эффективного метода.

Declare
  cnt PLS_INTEGER;
Begin
  For c In ( Select table_name From user_tables ) Loop
    begin
       Execute Immediate 'Select 1 From dual where exists (select 1 from ' || c.table_name ||')' Into cnt;
    exception when no_data_found then
      dbms_output.put_line( c.table_name );
    end;  
  End Loop;
End;
0 голосов
/ 19 мая 2010

Этот ответ на один Fetch-per-table более эффективен, чем ответ Рене. SELECT INTO требует Extra Fetch, чтобы увидеть, должно ли быть сгенерировано исключение "TOO_MANY_ROWS". Мы можем взять под контроль этот процесс с помощью явного курсора и НЕ делать ненужной дополнительной выборки.

Declare
  cnt PLS_INTEGER;
  s_Cur Varchar2(255);
  c_Cur Sys_refcursor;
Begin
   For c In ( Select table_name From user_tables ) Loop

      s_Cur := 'Select 1  From dual where exists (select 1 from ' || c.table_name ||')';    

      Open c_Cur For s_cur ;
      Fetch c_cur into cnt;        
      If c_cur%NOTFOUND then 
          dbms_output.put_line( c.table_name );
      end if;

   End Loop;
End;
0 голосов
/ 17 мая 2010
select TABLE_NAME
from USER_ALL_TABLES
where NUM_ROWS = 0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...