2012-05-10 5 views
12

나는 main 데이터베이스와 report 데이터베이스를 가지고 있으며 main에서 report으로 테이블을 동기화해야합니다.Oracle SQL에서 MERGE를 수행 할 때 SOURCE와 일치하지 않는 행을 어떻게 업데이트 할 수 있습니까?

그러나 항목이 main 데이터베이스에서 삭제되면 report 데이터베이스에 IsDeleted 플래그 만 설정하고 싶습니다.

어떻게하면 좋을까요?

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의 모든 새로운 가치를 제공하지만, 또한 report에서 모든 OLD 값을 업데이트 할 :

나는 현재이처럼 MERGE 문을 사용하고 있습니다.

Oracle PL/SQL을 사용하고 있습니다.

+0

'main.test'를 업데이트하려는 값은 무엇입니까? 어디서 구해 줄거야? –

+0

행이'main.test'에서 삭제되면 해당 'report.test' 행이 일치하지 않습니다. 일치하지 않는 모든 행에 대해'report.test.IsDeleted' 플래그를 설정하고 싶습니다. –

+0

기본 JOIN ('using (...)')의 결과가 해당 행을 포함하지 않기 때문에 가능하지 않다고 생각합니다. 그 데이터는 어디서 오는 것이 좋습니까? –

답변

11

당신은 내가 당신의 MERGE 문에이를 통합 할 수있는 방법을 알고하지 않는 별도의 UPDATE 문

UPDATE report.TEST target 
SET is Deleted = 'Y' 
WHERE NOT EXISTS (SELECT 1 
        FROM main.TEST source 
        WHERE source.ID = target.ID); 

와 함께 할 수 있습니다.

+0

MERGE로이 작업을 수행 할 수 없다는 것이 이상하게 보입니다. 나는이 대답을 고려할 것이다. –

+0

"OUTER JOIN"을 수행하고 "main.test가 null 인"위치를 업데이트하면 더 "우아"/ 효율적이겠습니까? –

+1

여기에 관련된 질문이 있어요 http://stackoverflow.com/questions/4863960/could-somebody-explain-what-the-merge-statement-really-does-in-oracle, 나는 그것이 외부 조인을 할거라고 생각합니다. 완전 외부 조인이 아니므로, 당신이 제안한 것이 효과가 있다고 생각하지 않습니다. –

4
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 
+0

창의력에 감사드립니다. 나는이 일을하지 않을 것이지만 일을 끝내게됩니다. –

-1
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' ; 
+0

어디에서이 구문을 발견 했습니까? ('by target') –

+0

이것은 정확하게 내가 찾고있는 것입니다. 그러나 @FlorinGhita가 말했듯이, 당신은이 구문을 어디에서 발견 했습니까? 이 MS SQL 구문입니까? –

+6

-1이 [SQL Server merge] (http://msdn.microsoft.com/en-us/library/bb510625.aspx) 구문이므로 [Oracle merge] (http://docs.oracle.com/cd /E11882_01/server.112/e26088/statements_9016.htm#SQLRF01606) – user272735

2

다음 답 USER_IDUSER_NAME가 일치 할 경우 다음과 일치하지 않을 경우

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'); 

이 명령 검사가 그것이 삽입 것 같은 테이블에 병합 데이터이다.