Процедура Oracle для вставки всех записей из одной промежуточной таблицы в основную таблицу

#sql #oracle #stored-procedures #plsql

Вопрос:

Я написал Stored Procedure (SP) , где внутри SP, 2 SP отделены для вставки 2 из таблицы. Обе таблицы содержат более 25 столбцов в каждой временной и основной таблице. Ниже приведен запрос-

 create or replace procedure sp_main as   procedure tbl1_ld as   cursor c1 is select * from tmp1;  type t_rec1 is table of c1%rowtype;  v_rec1 t_rec1;  begin  open c1;  loop  fetch c1 bulk collect into v_rec1 limit 1000;  exit when v_rec1.count=0;  insert into tbl1 values v_rec1;  end loop;  end tbl1_ld;   procedure tbl2_ld as   cursor c2 is select * from tmp2;  type t_rec2 is table of c2%rowtype;  v_rec2 t_rec2;  begin  open c2;  loop  fetch c2 bulk collect into v_rec2 limit 1000;  exit when v_rec2.count=0;  insert into tbl2 values v_rec2;  end loop;  end tbl2_ld;  begin  null; end sp_main; /  

Я использовал EXECUTE IMMEDIATE 'insert into tbl1 select * from tmp1'; для вставки внутри обоих SP tbl1_ld amp; tbl2_ld вместо использования cursor , SP скомпилирован, но запись не была вставлена.

Ответ №1:

Ну, на самом деле вы не проводили ни одну из этих процедур. Последние несколько строк вашего кода должны быть

 lt;snipgt;  end tbl2_ld;  begin  tbl1_ld; --gt; this  tbl2_ld --gt; this end sp_main; /  

С другой стороны, я предпочитаю избегать insert into ... select * from , потому что он просто любит терпеть неудачу, когда вы изменяете описание таблиц и не исправляете код, который использует эти таблицы.

Да, я знаю — просто скучно называть все 25 колонок, но — по-моему — оно того стоит. Поэтому я бы просто

 begin  insert into tbl1 (id, name, address, phone, ... all 25 columns)  select id, name, address, phone, ... all 25 columns  from tmp1;   insert into tbl2 (id, name, address, phone, ... all 25 columns)  select id, name, address, phone, ... all 25 columns  from tmp2; end;  

Другими словами, никаких курсоров, типов, циклов … ничего. Возможно, это был чистый SQL (т. е. без PL/SQL). Если вы хотите ограничить количество вставляемых строк, используйте, например ... where rownum lt;= 1000 (если именно поэтому вы использовали limit предложение).


Что касается динамического SQL, о котором вы упомянули ( execute immediate ): зачем вы его используете? В написанном вами коде нет ничего динамичного.

Комментарии:

1. «потому что он просто любит терпеть неудачу, когда вы изменяете описание таблиц и не исправляете код, который использует эти таблицы» . Другой взгляд на вещи заключается в том, что это функция, а не ошибка. Иногда нам нужны структуры таблиц для синхронизации; на складе у нас могут быть временные промежуточные таблицы и постоянные архивные таблицы, которые должны иметь соответствующие проекции. В таких случаях использование select * from действует как канарейка, напоминающая нам о необходимости изменить обе таблицы. Я признаю, что это не распространенный вариант использования, но я с ним сталкивался, и, похоже, он может соответствовать сценарию Искателя.