Как объявить числовую переменную, где я могу сохранить количество таблиц в моем цикле - PullRequest
1 голос
/ 21 марта 2019

Я работаю с базой данных оракула. У меня есть код plsql, где я запускаю запрос в цикле для нескольких таблиц. Итак, имя таблицы является переменной в моем коде. Я хотел бы иметь другую переменную (одно число), которую я могу вызывать внутри цикла, и каждый раз, когда она подсчитывает общее количество строк каждой таблицы для меня

declare
  Cursor C_TABLE  is 
    select trim(table_name) as table_name
      from all_tables
     where table_name in ('T1', 'T2', 'T3');

  V_ROWNUM number;

begin
    for m in C_TABLE
      loop 
          for i in ( select column_name 
                      from (
                          select c.column_name
                             from all_tab_columns c
                            where c.table_name = m.table_name 
                              and c.owner = 'owner1' 
                            )  
                    )       
                 loop

                 --I have this:
                  execute immediate ' insert into MY-table value (select ' || i.column_name || ' from ' || m.table_name  || ')';

                 --I want this but it does not work of course: 
                  V_ROWNUM := execute immediate 'select count(*) from ' || m.table_name;
                  execute immediate ' insert into MY-table value (select ' || i.column_name || ', ' || V_ROWNUM || ' from ' || m.table_name  || ')';

                    end loop;
    end loop;
end;
/

Я считаю, что не использую "вставить в", потому что я выбираю не из 1 таблицы, а из таблицы, которую я хочу выбирать, каждый раунд.

Ответы [ 2 ]

3 голосов
/ 21 марта 2019

В вашем динамическом SQL три вещи неправильные.

  1. EXECUTE IMMEDIATE не является функцией: правильный синтаксис: execute immediate '<<query>>' into <<variable>>.
  2. Инструкция INSERT принимает предложение VALUESили ВЫБРАТЬ, но не оба.SELECT было бы очень неправильно в этом случае.Также обратите внимание, что это ЗНАЧЕНИЯ, а не ЗНАЧЕНИЕ.
  3. COLUMN_NAME - это строковый литерал в динамическом SQL, поэтому он должен быть в кавычках.Но поскольку оператор SQL сам по себе является строкой, кавычки в динамических строках необходимо экранировать, поэтому это должно быть `'' '|| column_name ||' '.

Таким образом, исправленная версия будет выглядетьчто-то вроде этого

declare
  Cursor C_TABLE  is 
    select trim(table_name) as table_name
      from all_tables
     where table_name in ('T1', 'T2', 'T3');

  V_ROWNUM number;

begin
    for m in C_TABLE
      loop 
          for i in ( select column_name 
                      from (
                          select c.column_name
                             from all_tab_columns c
                            where c.table_name = m.table_name 
                              and c.owner = 'owner1' 
                            )  
                    )       
     loop
         execute immediate 'select count(*) from ' || m.table_name into  V_ROWNUM;
         execute immediate 'insert into MY_table values ( ''' || i.column_name || ''', ' || V_ROWNUM || ')';

        end loop;
    end loop;
end;
/

Динамический SQL сложен, потому что он превращает ошибки компиляции в ошибки времени выполнения.Рекомендуется сначала писать операторы как статический SQL.Как только вы освоите базовый синтаксис, вы можете преобразовать его в динамический SQL.

2 голосов
/ 21 марта 2019

Вы не можете присвоить результат выполнения немедленно переменной. это не функция.

но вы можете сделать это, используя into_clause например,

 execute immediate 'select count(*) from ' || m.table_name into V_ROWNUM ;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...