Вставка в несколько таблиц Oracle (Multi table insert)

«Multi table insert» или вставка одним запросом в несколько таблиц. Наверняка многим не хватало такой фишки, кто как реализовывал ее, но не знали, что это можно реализовать средствами Oracle.

Сегодня встретил заметку в блоге «System Engineering and RDBMS», в которой описывались конструкции, позволяющие делать вставки в несколько таблиц одним запросом. Сразу скажу, что все это возможно для версий 9i и выше.
Пример:

create table TAB1 (COL1 NUMBER(30), COL2 NUMBER(30) );
create table TAB2 (COL3 NUMBER(30), COL4 DATE);
CREATE SEQUENCE TEST_SEQ INCREMENT BY 1;
insert
when mod( object_id, 2 ) = 1 then
into TAB1 ( COL1, COL2 ) values ( test_seq.nextval, object_id )
when mod( object_id, 2 ) = 0 then
into TAB2 ( COL3, COL4 ) values ( test_seq.nextval, created )
select object_id, created from all_objects;

Т.е. между INSERT и запросом с исходными данными у нас идет конструкция:

Двумя словами можно описать следующим образом (для тех, у кого плохо с чтением подобных карт):
По некому условию (в качестве параметров условия можно брать значения из исходного запроса) мы делим вставку на несколько, т.е. в зависимости от исходных данных формируем отдельные вставки в разные таблицы либо в одну таблицу но, допустим, в разном формате. Кроме того, мы можем по одному условию делать вставки в несколько таблиц:


INSERT ALL
      INTO sales (prod_id, cust_id, time_id, amount)
      VALUES (product_id, customer_id, weekly_start_date, sales_sun)
      INTO sales (prod_id, cust_id, time_id, amount)
      VALUES (product_id, customer_id, weekly_start_date+1, sales_mon)
      INTO sales (prod_id, cust_id, time_id, amount)
      VALUES (product_id, customer_id, weekly_start_date+2, sales_tue)
      INTO sales (prod_id, cust_id, time_id, amount)
      VALUES (product_id, customer_id, weekly_start_date+3, sales_wed)
      INTO sales (prod_id, cust_id, time_id, amount)
      VALUES (product_id, customer_id, weekly_start_date+4, sales_thu)
      INTO sales (prod_id, cust_id, time_id, amount)
      VALUES (product_id, customer_id, weekly_start_date+5, sales_fri)
      INTO sales (prod_id, cust_id, time_id, amount)
      VALUES (product_id, customer_id, weekly_start_date+6, sales_sat)
   SELECT product_id, customer_id, weekly_start_date, sales_sun,
      sales_mon, sales_tue, sales_wed, sales_thu, sales_fri, sales_sat
      FROM sales_input_table;

(из примера в документации)
Еще один важный момент, сразу после INSERT указывается ALL (по-умолчанию) либо FIRST, в первом случае все условия проверяются и выполняются все вставки, результат вычисления значений у которых TRUE, во втором варианте проверяются все условия в порядке их указания в запросе до первого FALSE. Вставка, указанная в ELSE, будет выполнена если не выполнено ни одно условие.
Еще несколько примеров из доки:

INSERT ALL
  WHEN order_total <> 1000000 AND order_total <> 2000000 THEN
     INTO large_orders
  SELECT order_id, order_total, sales_rep_id, customer_id
     FROM orders;

Выполняет то же самое что и

INSERT ALL
  WHEN order_total <> 1000000 AND order_total < 2000000 THEN
      INTO medium_orders
   ELSE
      INTO large_orders
   SELECT order_id, order_total, sales_rep_id, customer_id
      FROM orders;

А следующий пример вставляет заказы больше 2900000 в таблицу special_orders, но не вставляет в large_orders:

INSERT FIRST
  WHEN ottl <> 1000000 and ottl <> 2900000 THEN
     INTO special_orders
  WHEN ottl > 2000000 THEN
     INTO large_orders
        VALUES(oid, ottl, sid, cid)
  SELECT o.order_id oid, o.customer_id cid, o.order_total ottl,
     o.sales_rep_id sid, c.credit_limit cl, c.cust_email cem
     FROM orders o, customers c
     WHERE o.customer_id = c.customer_id;
09:39
353
Нет комментариев. Ваш будет первым!
Загрузка...