Вставьте несколько строк с помощью инструкции SQL Merge при совпадении условия

Иметь таблицу с неидентифицирующим первичным ключом. поэтому всякий раз, когда мы вставляем новую запись, мы также должны передавать первичный ключ.

Я должен вставить в приведенную выше таблицу, когда запись не соответствует оператору слияния. Но проблема в том, что я не мог увеличивать первичный ключ для каждой вставки. он не может вставить дубликат в столбец первичного ключа. Ниже приведен пример запроса на слияние.

Можно ли вставить несколько строк путем увеличения первичного ключа.

MERGE DBO.Table1 T1
        USING (DBO.Table2 )T2
        ON (T1.ID = T2.ID)
        WHEN MATCHED
            THEN UPDATE SET 
            T1.CURVE = T2.CURVE
        WHEN NOT MATCHED
            THEN INSERT (ID, CURVE )
            Values ( T2.ID, T2.CURVE);

person Rajkumar Selvara    schedule 16.01.2020    source источник
comment
Какая у вас RDBMS (MS Sql, Oracle и т. д.)?   -  person Dmitry Bychenko    schedule 16.01.2020
comment
@DmitryBychenko Это MS SQL   -  person Rajkumar Selvara    schedule 16.01.2020
comment
Во-первых, вы MERGE на T2.ID, но вставляете VALUES(T2.ProductID ..., это опечатка? Если нет, это может быть вашей проблемой, это ничего не говорит о том, что T2.ProductID уже существует или нет. Во-вторых, Вы уверены, что T2.ID (или ProductID) соответствует требованиям первичного ключа (уникальный, ненулевой)?   -  person Robert Sheahan    schedule 16.01.2020
comment
@RobertSheahan Извините, это моя ошибка. это T2.ID. Да, если условие соответствует, то совпадающие строки обновляются, но для тех строк, которые не соответствуют условию, я не могу вставить повторяющуюся ошибку. Надеюсь, я ответил на ваш запрос. Пожалуйста, дайте мне знать, если вам нужна дополнительная информация.   -  person Rajkumar Selvara    schedule 16.01.2020


Ответы (1)


Код в вашем примере работает, вот демо, которое легко воспроизвести

;with cteT as ( SELECT * FROM (VALUES (1,'T1 Val 1') , (2,'T1 Val 2') , (4,'T1 Val 4') ) as T1(ID, Curve)
)SELECT * INTO #Dest FROM cteT

;with cteT as ( SELECT * FROM (VALUES (3,'T2 Val 3') , (4,'T2 Val 4') , (5,'T2 Val 5') ) as T1(ID, Curve)
)SELECT * INTO #Srce FROM cteT;

MERGE INTO #Dest as T1
USING #Srce as T2 ON T1.ID=T2.ID
    WHEN MATCHED THEN UPDATE SET T1.Curve=T2.CURVE
    WHEN NOT MATCHED BY TARGET 
        THEN INSERT (ID, Curve) VALUES(T2.ID, T2.Curve)
;

SELECT * FROM #Dest ORDER BY ID

DROP TABLE #Dest
DROP TABLE #Srce

Это вывод, обратите внимание, что для 1 и 2 значение не изменилось, для 4 оно обновлено из T2, а для 3 и 5 оно вставлено из T2.

ID  Curve
1   T1 Val 1
2   T1 Val 2
3   T2 Val 3
4   T2 Val 4
5   T2 Val 5

Это означает, что, скорее всего, проблема либо в ваших значениях для T2.ID, либо ваш образец слишком урезан и пропускает сложность в вашем реальном коде. Я бы начал с проверки ваших данных в T2.ID

SELECT ID, COUNT(ID) as IDCount FROM DBO.Table2 GROUP BY ID HAVING COUNT(*) > 1
SELECT * FROM DBO.Table2 WHERE ID IS NULL

и посмотрите, появятся ли какие-либо записи. Если они оба пусты, посмотрите на свой фактический код слияния и посмотрите, как он может отличаться от того, что вы разместили. Если вы опубликуете обновленный пример кода, я постараюсь посмотреть.

person Robert Sheahan    schedule 16.01.2020