Вставка в несколько таблиц Oracle (Multi table insert)
«Multi table insert» или вставка одним запросом в несколько таблиц. Наверняка многим не хватало такой фишки, кто как реализовывал ее, но не знали, что это можно реализовать средствами Oracle.
Сегодня встретил заметку в блоге «System Engineering and RDBMS», в которой описывались конструкции, позволяющие делать вставки в несколько таблиц одним запросом. Сразу скажу, что все это возможно для версий 9i и выше.
Пример:
CREATE SEQUENCE TEST_SEQ INCREMENT BY #cc66cc;">1; insert into TAB1 ( COL1, COL2 ) values ( test_seq.nextval, object_id ) 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) INTO sales (prod_id, cust_id, time_id, amount) INTO sales (prod_id, cust_id, time_id, amount) INTO sales (prod_id, cust_id, time_id, amount) INTO sales (prod_id, cust_id, time_id, amount) INTO sales (prod_id, cust_id, time_id, amount) 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 INTO large_orders SELECT order_id, order_total, sales_rep_id, customer_id FROM orders;
Выполняет то же самое что и
INSERT ALL INTO medium_orders #b1b100;">ELSE INTO large_orders SELECT order_id, order_total, sales_rep_id, customer_id FROM orders;
А следующий пример вставляет заказы больше 2900000 в таблицу special_orders, но не вставляет в large_orders:
INSERT FIRST INTO special_orders WHEN ottl > #cc66cc;">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;