#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
действует как канарейка, напоминающая нам о необходимости изменить обе таблицы. Я признаю, что это не распространенный вариант использования, но я с ним сталкивался, и, похоже, он может соответствовать сценарию Искателя.