2010-12-02 3 views
4

기본적으로 UPSERT를 수행하기 위해 MERGE 문을 사용하고 있습니다. 대상에없는 행의 경우 특정 순서로 삽입하려고합니다. 아쉽게도 ORDER BY 절이 병합 문과 함께 지원되지 않습니다. 한 진술에서 어떤 식 으로든 이것을 할 수 있습니까? 내가 뭘하려고 오전의 더 나은 아이디어에 대한 예를 참조하십시오 : 나는이 병합을 수행 내 코드에 대한 단위 테스트를 작성하고자한다이 작업을 수행 할 수있는 이유를일치하지 않는 행을 SQL Server 2008 MERGE 문에 삽입하는 순서를 지정할 수 있습니까?

CREATE TABLE #destination (ident int not null identity(1,1), id int not null, value int not null) 
INSERT INTO #destination (id,value) VALUES (1,50) 

CREATE TABLE #source (id int not null, value int not null) 
INSERT INTO #source (id,value) VALUES (1,100),(3,300),(2,200) 

MERGE #destination d 
USING #source s 
    ON d.id = s.id 
WHEN MATCHED THEN 
    UPDATE 
    SET d.value = s.value 
WHEN NOT MATCHED THEN 
    INSERT (id,value) 
    VALUES (s.id,s.value); 

SELECT * FROM #destination ORDER BY ident 
/* 
WILL LIKELY SEE: 
    1, 1, 100 
    2, 3, 300 
    3, 2, 200 
WANT TO ACHIEVE: 
    1, 1, 100 
    2, 2, 200 
    3, 3, 300 
*/ 

과 결정에 삽입을 원하는 주문. 나는이 문제를 해결할 방법이 있다는 것을 알고 있지만, 병합 삽입을 명령하는 방법이 있다면 그것은 가장 쉽다.

답변

2

지금은 불가능합니다. documentation on MERGE에서 삽입, 삭제 및 업데이트 작업의 순서가 지정되지 않습니다.

TOP 절은 추가로 지정된 값과 삽입, 업데이트에 합류 행의 수를 감소 또는 삭제 행동이 에 적용됩니다 : 그것은 TOP 그것을 어떻게 영향을 미치는지에 대한 설명은의에 있지만 묻혀 있었다 정렬되지 않은 채로 남아있는 행은 입니다. 즉, 행이 사이에 분포되어있는 에는 WHEN 절에 정의 된 작업 순서가 없습니다. 예를 들어 TOP (10)을 지정하면 10 개의 행에 영향을줍니다. 이 행 중 7 이 업데이트되고 3 개가 삽입되거나 1 이 삭제되고 5 개가 업데이트되고 4 개가 등으로 삽입 될 수 있습니다.

+0

견적을 통해 행의 순서가 없다는 것을 분명히 알 수 있지만 작업에 대해 궁금합니다. 적어도 두 가지 예에서 업데이트는 삽입하기 전에 제공됩니다. 따라서 작업이 같은 순서로 수행 될 수 있습니까? 삭제, 업데이트 및 삽입? 이 영향을 줄 수있는 방법이 있습니까? –

1

귀하의 경우에 허용 될지 확실하지 않지만 SET IDENTITY_INSERT을 사용하여 신원 열을 무시하고 주문 방식을 보장 할 수 있습니다.

CREATE TABLE #destination (ident int not null identity(1,1), id int not null, value int not null) 
INSERT INTO #destination (id,value) VALUES (1,50) 

CREATE TABLE #source (id int not null, value int not null) 
INSERT INTO #source (id,value) VALUES (1,100),(3,300),(2,200) 

SET IDENTITY_INSERT #destination ON 

MERGE #destination d 
USING #source s 
    ON d.id = s.id 
WHEN MATCHED THEN 
    UPDATE 
    SET d.value = s.value 
WHEN NOT MATCHED THEN 
    INSERT (ident,id,value) 
    VALUES (s.id, s.id, s.value); 

SET IDENTITY_INSERT #destination OFF 

SELECT * FROM #destination ORDER BY ident 
+0

내 예제는 id가 id와 동일한 매우 간단하기 때문에이 경우에는 작동한다고 생각합니다. 그러나 순차적이지만 동일하거나 순차적 인 ID 열을 보장하지 않는 ID 열이 필요하다면 분해됩니다. 다시 말해, 주문하려는 모든 이유가 ID 열에 대해 걱정할 필요가 없기 때문입니다. – Zugwalt

관련 문제