2012-05-22 2 views
19

Я пытаюсь получить количество отсчетов всех таблиц в схеме. У меня возникли проблемы с написанием 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; 
+2

Было бы полезно, если бы вы разместили свои ошибки вместо того, чтобы пытаться нас угадать. К счастью, вы сделали пару классических блаузеров, поэтому на этот раз это простая игра. – APC

ответ

19

Это следует сделать это:

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; 

Я удалил различные ошибки из вашего кода.

+1

Маленькая опечатка: значение l_count должно быть в значениях INSERT должно быть v_count – Ram

+0

@Ram, спасибо - исправлено –

+3

Несколько вариантов, чтобы предложить ... Недавно я полюбил построение SQL, который будет выполняться в предложении selet неявного курсора, так как он позволяет вам запустить выбор и посмотреть, какая инструкция сгенерирована. Можно также построить оператор insert как динамический SQL и объединить вставку и выбрать одну операцию. Всего несколько вариантов ... –

40

Это может быть сделано с помощью одного оператора и некоторые 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' 
+2

Только то, что мне нужно. :) Хороший код. – BobRodes

0

Вы должны использовать выполнить непосредственный (динамический 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; 
4
select owner, table_name, num_rows, sample_size, last_analyzed from all_tables; 

Это самый быстрый способ извлечения числа строк, но есть несколько важных предостережений:

  1. NUM_ROWS только 100% точный, если были собраны статистические данные в 11g и выше с ESTIMATE_PERCENT => DBMS_STATS.AUTO_SAMPLE_SIZE (по умолчанию) или в более ранних версиях с ESTIMATE_PERCENT => 100. См. this post для объяснения того, как алгоритм AUTO_SAMPLE_SIZE работает в 11g.
  2. Результаты были созданы с LAST_ANALYZED. Текущие результаты могут отличаться.
3

Если вы хотите простой SQL для Oracle (например, у ХЕ с не XmlGen) пойти на простой 2 шага:

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

Скопируйте весь результат и заменить последний UNION с запятой (';'). Затем в качестве второго шага выполните полученный SQL.

+0

Если есть много таблиц, я думаю, что копирование результатов занимает много времени. –

Смежные вопросы