#sql #oracle #plsql
#sql #Oracle #plsql
Вопрос:
CREATE TABLE main_quest( e_id NUMBER(10) NOT NULL, CONSTRAINT pk_main_quest PRIMARY KEY ( e_id )); insert into main_quest values(11); insert into main_quest values(12); insert into main_quest values(13); insert into main_quest values(14); insert into main_quest values(15); insert into main_quest values(16); insert into main_quest values(17); insert into main_quest values(18); CREATE TABLE quest_staging ( e_id NUMBER(10), data_separator VARCHAR2(100), CONSTRAINT pk_quest_staging PRIMARY KEY ( e_id ) ); insert into quest_staging values(11,'P'); insert into quest_staging values(12,'R'); insert into quest_staging values(13,'R P'); insert into quest_staging values(14,'C'); insert into quest_staging values(15,'C P'); insert into quest_staging values(20,'C P'); CREATE TABLE quest_ref ( ref_id NUMBER(10), ref_cat VARCHAR2(50), ref_value VARCHAR2(100), CONSTRAINT pk_quest_ref PRIMARY KEY ( ref_id ) ); insert into quest_ref values(1,'cat_1','PP'); insert into quest_ref values(2,'cat_1','R'); insert into quest_ref values(3,'cat_1','R P'); insert into quest_ref values(4,'cat_1','C'); insert into quest_ref values(5,'cat_1','C P'); insert into quest_ref values(6,'cat_1','I'); insert into quest_ref values(7,'cat_1','I P'); insert into quest_ref values(8,'cat_1','P'); CREATE SEQUENCE quest_main_sq; CREATE TABLE quest_main ( main_id number(10) DEFAULT quest_main_sq.NEXTVAL NOT NULL, e_id NUMBER(10), ref_quest_id NUMBER(10), CONSTRAINT pk_quest_main PRIMARY KEY ( main_id ), CONSTRAINT fk_quest_main FOREIGN KEY ( e_id ) REFERENCES main_quest ( e_id ) );
Моя Попытка :
MERGE INTO quest_main m USING (SELECT n.e_id, n.data_separator, qr.ref_id separator FROM quest_staging n JOIN quest_ref qr ON qr.ref_value = n.data_separator AND qr.ref_cat = 'cat_1' ) x ON (m.e_id = x.e_id) WHEN MATCHED THEN UPDATE SET m.ref_quest_id = x.separator WHEN NOT MATCHED THEN INSERT (main_id, e_id, ref_quest_id ) VALUES (quest_main_sq.nextval, x.e_id, x.separator );
Проблема: Я хочу вставить записи в основную таблицу таблицы, т. е. quest_main, на основе промежуточной таблицы, т. е. quest_staging и таблицы поиска, т. е. quest_ref. Если столбец data_separator в промежуточной таблице совпадает со столбцом ref_value в таблице поиска, то вставка произойдет в основную таблицу. И данные, присутствующие в промежуточной таблице, являются подмножеством таблицы main_quest. Таким образом, если e_id отсутствует в таблице main_quest при вставке записей из промежуточной таблицы, то она должна пропустить эту запись и вставить оставшуюся. Но здесь я получаю такие ошибки, как Сообщение об ошибке — ORA-02291: нарушено ограничение целостности (TAM.FK_QUEST_MAIN) — родительский ключ не найден, поскольку e_id 20 отсутствует в таблице main_quest. Но мне нужно справиться с этим, чтобы он пропустил e_id 20 и вставил оставшийся.
Используемый инструмент: SQL Версия разработчика: 20.4.1.407.0006
Ответ №1:
Если я вас правильно понял, это всего лишь WHERE
пункт, USING
который исправляет это (см. Строки № 7-10).:
SQLgt; MERGE INTO quest_main m 2 USING (SELECT n.e_id, n.data_separator, qr.ref_id separator 3 FROM quest_staging n 4 JOIN quest_ref qr 5 ON qr.ref_value = n.data_separator 6 AND qr.ref_cat = 'cat_1' 7 WHERE EXISTS 8 (SELECT NULL 9 FROM main_quest m 10 WHERE m.e_id = n.e_id)) x 11 ON (m.e_id = x.e_id) 12 WHEN MATCHED 13 THEN 14 UPDATE SET m.ref_quest_id = x.separator 15 WHEN NOT MATCHED 16 THEN 17 INSERT (main_id, e_id, ref_quest_id) 18 VALUES (quest_main_sq.NEXTVAL, x.e_id, x.separator); 5 rows merged.
Результат:
SQLgt; select * from quest_main; MAIN_ID E_ID REF_QUEST_ID ---------- ---------- ------------ 24 12 2 26 13 3 28 14 4 30 15 5 32 11 8 SQLgt;
P.S. Спасибо за тестовый кейс!
Комментарии:
1. Спасибо за это. Не могли бы вы, пожалуйста, сообщить мне, почему мы использовали EXISTS здесь
2. Чтобы избежать значений, которых нет в родительской таблице.