Можете ли вы указать порядок, в который несопоставленные строки вставляются в оператор SQL Server 2008 MERGE? - PullRequest
4 голосов
/ 02 декабря 2010

Я использую оператор MERGE, чтобы в основном выполнить UPSERT.Для строк, которых нет в месте назначения, я бы хотел, чтобы они были вставлены в определенном порядке.К сожалению, кажется, что предложение ORDER BY не поддерживается оператором слияния.Есть ли способ сделать это в одном утверждении?Смотрите пример для лучшего понимания того, что я пытаюсь сделать:

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
*/

Причина, по которой я хочу это сделать, заключается в том, что я хотел бы написать модульный тест для моего кода, который выполняет это слияние и хочу вставкидетерминированный порядок.Я знаю, что есть способы обойти это, но если есть способ заказать вставку MERGE, это будет проще всего.

Ответы [ 2 ]

2 голосов
/ 03 января 2011

Так что сейчас это невозможно. Из документации в MERGE операция вставки, удаления и обновления неупорядочена; но это было скрыто в объяснении того, как TOP влияет на это:

Предложение TOP еще больше уменьшает количество соединенных строк до указанного значение и вставка, обновление или действия удаления применяются к оставшиеся соединенные строки в неупорядоченном мода. То есть нет порядка в которые строки распределены между действия, определенные в WHEN статьи. Например, указав TOP (10) влияет на 10 строк; из этих рядов 7 может быть обновлено и 3 вставлено, или 1 могут быть удалены, 5 обновлены и 4 вставлен и т. д.

1 голос
/ 02 декабря 2010

Не уверен, что это будет приемлемо в вашем случае, но вы можете использовать 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
...