Oracle 12c - вставка значений в таблицу с использованием значений из другой таблицы
У меня есть стол (TABLEA
) вот так:
type_id level
1 7
2 4
3 2
4 5
И еще один столик (TABLEB
) вот так:
seq_id type_id name order level
1 1 display 1 7
2 1 header 2
3 1 detail 3
4 2 display 1 4
5 2 header 2
6 2 detail 3
TABLEB.TYPE_ID
это ФК в TABLEA.TYPE_ID
, В настоящее время я ввожу данные в TABLEB
вручную.
У меня есть 2 новые строки в TABLEA
.. type_id 3 и 4.
Как я могу заполнить данные, которые не существуют в TABLEB
автоматически используя TABLEA
? Я хотел бы, чтобы все столбцы в TABLEB
быть вставленным автоматически.
Итак, как вы можете видеть:
SEQ_ID
будет последовательным- когда
ORDER
значение равно 1,NAME
значение будет "отображать", иLEVEL
будет 7 - когда
ORDER
значение равно 2,NAME
значение будет "заголовок" - когда
ORDER
значение 3,NAME
значение будет "деталь"
Я ожидаю после вставки:
seq_id type_id name order level
1 1 display 1 7
2 1 header 2
3 1 detail 3
4 2 display 1 4
5 2 header 2
6 2 detail 3
7 3 display 1 2
8 3 header 2
9 3 detail 3
10 4 display 1 5
11 4 header 2
12 4 detail 3
Любая помощь приветствуется!
2 ответа
Вы также можете:
Сделайте так, чтобы код вашего приложения заполнял обе таблицы, т. Е. Вставлял соответствующие записи в обе таблицы.
(Звучит так, будто вы склоняетесь к этому) Попросите Oracle сделать работу за кулисами, то есть: Oracle делает вставки в
TABLEB
для тебя. Способ сделать это, создав TRIGGER наTABLEA
, Вот пример, с которого можно начать: /questions/38932321/sozdat-trigger-dlya-vstavki-v-druguyu-tablitsu/38932331#38932331
Некоторые люди скажут вам, что TRIGGER может затруднить отладку, потому что часть вашей логики находится в базе данных. В этой критике есть основания. Я не буду говорить всегда / никогда не использовать триггеры. Используйте их там, где они имеют смысл: где ценность, которую они предоставляют, перевешивает их сложность.
Так что это можно сделать на чистом SQL: INSERT ALL, что позволяет нам выполнять несколько вставок в одном выражении.
insert all
into tableb (seq_id, type_id, name, order_id, level_id)
values(tableb_id_seq.nextval, type_id, 'display', 1, level_id)
into tableb (seq_id, type_id, name, order_id)
values(tableb_id_seq.nextval+1, type_id, 'header', 2)
into tableb (seq_id, type_id, name, order_id)
values(tableb_id_seq.nextval+2, type_id, 'detail', 3)
select a.type_id, a.level_id from tablea a
minus
select b.type_id, b.level_id from tableb b
/
Манипулирование последовательностью немного забавно: это необходимо, потому что каждый вызов NEXTVAL возвращает одно и то же значение в одном выражении. Очевидно, чтобы эта работа работала, последовательность должна быть увеличена на три:
create sequence tableb_id_seq increment by 3;
Этого может быть достаточно, чтобы исключить такой подход. В качестве альтернативы вы можете использовать (SEQ_ID, ORDER_ID) в качестве составного первичного ключа, но это тоже не очень хорошо.
Кстати, ORDER и LEVEL являются ключевыми словами: их нельзя использовать в качестве имен столбцов.