При выполнении MERGE в Oracle SQL, как я могу обновлять строки, которые не совпадают в SOURCE?
У меня есть база данных main
и база данных report
, и мне нужно синхронизировать таблицу с main
в report
.
Однако, когда элемент удаляется в базе данных main
, я хочу установить флаг IsDeleted
в базе данных report
.
Каков элегантный способ сделать это?
В настоящее время я использую оператор MERGE, например:
MERGE INTO report.TEST target
USING (SELECT * FROM main.TEST) source
ON (target.ID = source.ID)
WHEN MATCHED THEN
UPDATE SET (target... = source...)
WHEN NOT MATCHED THEN
INSERT (...) VALUES (source...)
;
Оператор WHEN NOT MATCHED
дает мне все НОВЫЕ значения из main
, но я также хочу обновить все значения OLD от report
.
Я использую Oracle PL/SQL.
Ответы
Ответ 1
Вы можете сделать это с помощью отдельного оператора UPDATE
UPDATE report.TEST target
SET is Deleted = 'Y'
WHERE NOT EXISTS (SELECT 1
FROM main.TEST source
WHERE source.ID = target.ID);
Я не знаю, как это интегрировать в ваш оператор MERGE.
Ответ 2
MERGE INTO target
USING
(
--Source data
SELECT id, some_value, 0 deleteMe FROM source
--And anything that has been deleted from the source
UNION ALL
SELECT id, null some_value, 1 deleteMe
FROM
(
SELECT id FROM target
MINUS
SELECT id FROM source
)
) source
ON (target.ID = source.ID)
WHEN MATCHED THEN
--Requires a lot of ugly CASE statements, to prevent updating deleted data
UPDATE SET target.some_value =
CASE WHEN deleteMe=1 THEN target.some_value ELSE source.some_value end
,isDeleted = deleteMe
WHEN NOT MATCHED THEN
INSERT (id, some_value, isDeleted) VALUES (source.id, source.some_value, 0)
--Test data
create table target as
select 1 ID, 'old value 1' some_value, 0 isDeleted from dual union all
select 2 ID, 'old value 2' some_value, 0 isDeleted from dual;
create table source as
select 1 ID, 'new value 1' some_value, 0 isDeleted from dual union all
select 3 ID, 'new value 3' some_value, 0 isDeleted from dual;
--Results:
select * from target;
ID SOME_VALUE ISDELETED
1 new value 1 0
2 old value 2 1
3 new value 3 0
Ответ 3
Следующий ответ: объединить данные в ту же таблицу
MERGE INTO YOUR_TABLE d
USING (SELECT 1 FROM DUAL) m
ON ( d.USER_ID = '123' AND d.USER_NAME= 'itszaif')
WHEN NOT MATCHED THEN
INSERT ( d.USERS_ID, d.USER_NAME)
VALUES ('123','itszaif');
Эта команда проверяет, соответствуют ли USER_ID
и USER_NAME
, если они не совпадают, тогда она будет вставляться.
Ответ 4
merge into x as target using y as Source on target.ID = Source.ID
when not matched by target then insert
when matched then update
when not matched by source and target.ID is not null then
update whatevercolumn = 'isdeleted' ;