Oracle PL / SQL Замена цикла for для динамического SQL, помощь в изменении синтаксиса - PullRequest
0 голосов
/ 30 мая 2019

У меня есть цикл for, здесь:

BEGIN

for rws in (

select /*+parallel (4)*/ a.owner,a.table_name, round(sum(b.sum_bytes),2) TOT_OBJECT_SIZE_MB, EST_ONE_ROW_MB
from dba_tables@DB1 a, MV_PRD_SEG_DATA b
where a.table_name = b.segment_name
and a.table_name in
(select table_name from MV_PDU_TABLE where driver_table is null)
and a.owner in (select distinct productionschema from MV_PDU_TABLE c)
group by a.owner,a.table_name
order by a.table_name
)
loop

Данные извлекаются из цикла следующим образом путем ссылки на rws.:

execute immediate' select /*+parallel (4)*/ count(*) from ' ||rws.owner||'.'||rws.table_name || '@' || dblink into TOTAL_ROW_COUNT;

Теперь мне нужно заменить некоторые жестко закодированные ссылки на таблицы в операторе выбора на переменные.(Я буду объявлять их ранее в коде.)

Насколько я понимаю, теперь я должен переключиться на динамический SQL.

При этом вы можете увидеть здесь, как жестко закодированные таблицы теперь называются переменными:

BEGIN

v_sql1 := 'select /*+parallel (4)*/ a.owner,a.table_name, round(sum(b.sum_bytes),2) TOT_OBJECT_SIZE_MB, EST_ONE_ROW_MB
from dba_tables@NAB1 a, '|| v_Mv_name ||' b
where a.table_name = b.segment_name
and a.table_name in
(select table_name from '|| v_Mv_name ||' where driver_table is null)
and a.owner in (select distinct productionschema from '|| v_Mv_name ||' c)
group by a.owner,a.table_name
order by a.table_name';

Проблема в том ... как мне теперь управлять выводом данныхцикла?Я думаю, что я бы зациклился, просто используя переменную, содержащую SQL?:

for rws in (v_sql1)

loop

Если так, что теперь будет здесь?

execute immediate' select /*+parallel (4)*/ count(*) from ' <NO_IDEA_HOW_TO_REFERENCE_THE_DATA_IN_THE_LOOP_NOW> ' into TOTAL_ROW_COUNT;

Ответы [ 2 ]

2 голосов
/ 30 мая 2019

Вы также можете использовать RefCursor:

declare
   cur SYS_REFCURSOR;
   owner varchar2(30); 
   table_namevarchar2(30); 
   TOT_OBJECT_SIZE_MB number; 
   EST_ONE_ROW_MB number; 
   TOTAL_ROW_COUNT integer;
   v_sql1 varchar2(10000);

begin

v_sql1 := 'select /*+parallel (4)*/ a.owner,a.table_name, round(sum(b.sum_bytes),2) TOT_OBJECT_SIZE_MB, EST_ONE_ROW_MB
from dba_tables@NAB1 a, '|| v_Mv_name ||' b
where a.table_name = b.segment_name
and a.table_name in
(select table_name from '|| v_Mv_name ||' where driver_table is null)
and a.owner in (select distinct productionschema from '|| v_Mv_name ||' c)
group by a.owner,a.table_name
order by a.table_name';

   open cur for v_sql1;
   loop
      fetch cur into owner, table_name, TOT_OBJECT_SIZE_MB, EST_ONE_ROW_MB;
      exit when cur%NOTFOUND;
      execute immediate' select /*+parallel (4)*/ count(*) from '||table_name into TOTAL_ROW_COUNT;
   end loop;
end;

Обычно BULK COLLECT обеспечивает лучшую производительность.Однако, поскольку вы запускаете специальный запрос для каждой записи, я не думаю, что вы заметите какую-либо разницу в производительности.

2 голосов
/ 30 мая 2019

Вы можете сделать BULK COLLECT в коллекции записей, которые вы хотите вернуть, а затем перебрать коллекцию.

Вы можете легко использовать этот пример в своем скрипте.

DECLARE
 TYPE sizerec is RECORD ( owner dba_tables.owner%type, 
  table_name dba_tables.table_name%type,
  tot_object_size_mb number);
  TYPE srectab  is TABLE OF  sizerec;
  srec srectab;
  l_tab_name varchar2(40) := 'dba_tables';
BEGIN


EXECUTE IMMEDIATE 
'SELECT a.owner,a.table_name,round(SUM(b.bytes),2) tot_object_size_mb
  FROM '||l_tab_name||' a
JOIN dba_segments b ON a.table_name = b.segment_name where rownum < 10
GROUP BY a.owner,a.table_name ' BULK COLLECT INTO srec;

for i in srec.first..srec.last 
loop
  dbms_output.put_line(srec(i).owner||','||srec(i).table_name
                                    ||','||srec(i).tot_object_size_mb);
end loop;

END;
/

Выход

PL/SQL procedure successfully completed.

SYS,BOOTSTRAP$,65536
SYS,FILE$,65536
SYS,OBJERROR$,65536
SYS,UNDO$,65536
SYS,PROXY_DATA$,65536
SYS,OBJ$,10485760
SYS,PROXY_ROLE_DATA$,65536
SYS,OBJAUTH$,2097152
SYS,CON$,262144
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...