Перебрать код plsql для нескольких таблиц - PullRequest
0 голосов
/ 17 апреля 2019

Основная таблица должна обновляться ежедневно с использованием входных данных из двух источников в двух таблицах. Код plsql для обработки двух таблиц практически идентичен, за исключением имен таблиц. Мы должны отдельно регистрировать возможные ошибки данных во входных таблицах, поэтому необходимо выполнить код один раз для каждой из двух входных таблиц.

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

declare
   input_table varchar2(20);
begin
   for i in (select column_value as var from table(sys.ODCIvarchar2List('MIDGETS', 'GIANTS'))) loop
      if i.var = 'MIDGETS' then
         input_table := 'midget_table';
      elsif i.var = 'GIANTS' then
         input_table := 'giant_table';
      end if;

      for rec in (select col1, col2 from input_table) loop

         <the processing code>

      end loop;
end;
/

Проблема в том, что plsql, похоже, не знает, что input_table является переменной. Он «думает», что input_table буквально является именем таблицы, и возвращает ошибку (ORA-00942: таблица или представление не существует).

Так как это динамический код, тогда исполнилось EXECUTE IMMEDIATE:

declare
   input_table varchar2(20);
begin
   for ... 'MIDGETS', 'GIANTS' ... loop
      input_table := ...
      ...
   end loop;

   for rec in ( EXECUTE IMMEDIATE 'select col1, col2 from ' || input_table ) loop
      <processing>
   end loop;
end;
/

Но EXECUTE IMMEDIATE также не разрешен в этом контексте.

Есть ли способ вообще? Или единственный выход - сделать две копии файла .sql, одну для MIDGETS и одну для GIANTS?

1 Ответ

2 голосов
/ 17 апреля 2019

Вы можете использовать динамический запрос, как показано ниже

declare
   type crs_type is ref cursor;
   c crs_type;
   v_query     varchar2(2000);
   input_table varchar2(20);
   v_col1      midgets.col1%type; -- assuming identical data types for common named columns
   v_col2      midgets.col2%type;
begin
   for ... 'MIDGETS', 'GIANTS' ... loop
      input_table := ...
      ...
   end loop;


   v_query := 'select col1, col2 from ' || input_table;
   open c for v_query;
   loop
    fetch c into v_col1, v_col2;
    exit when c%notfound;
      <processing>
   end loop;
   close c;
end;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...