Я использую SqlBulkCopy для вставки партий записей на сервер. Если одна запись выходит из строя из-за уникального ограничения, я не хочу откатывать всю партию, но вместо этого хочу сделать обновление существующей записи.
Я надеялся, что смогу записать данные о неудачных записях, а затем, как только объемная вставка будет закончена, вернитесь и укажите их отдельно.
Однако я не вижу никакого способа сообщить SqlBulkCopy не откатывать транзакцию при сбое, а также как получить информацию о неудачной записи.
Я мог проверить, существует ли запись, прежде чем добавлять ее в SqlBulkCopy DataTable, но это добавит значительные накладные расходы.
Я проверил ответы здесь, которые показывают использование промежуточной таблицы и некоторых других sproc, чтобы сделать вставку / обновление после массовой вставки, но я думаю, что sproc должен будет обрабатывать каждую запись отдельно, чтобы либо вставить новую, либо обновить существующие записи - очень кропотливый.
Любые другие советы или ничего не изменились за последние 4 года?
Я бы не рекомендовал использовать оператор слияния. У него есть проблемы, см. Раздел «Предостережение с заявлением MERGE от SQL Server», первое из многих, и лично имхо. Мне трудно следовать и мало что может предложить в отношении простого заявления об обновлении вставки (не столь сладкого синтаксического сахара).
INSERT INTO A
SELECT *
FROM #B B
LEFT OUTER JOIN A
ON A.ID = B.ID
WHERE A.ID IS NULL
или
UPDATE A
SET BLAH = 'BLAH'
FROM A
INNER JOIN #B B
ON B.ID = A.ID
Если вы настроены на инструмент, а не на чистый sql, вы можете посмотреть в SSIS, который может обрабатывать то, что вы ищете.
Не используйте SqlBulkCopy.
Непосредственно.
Вставьте в темповую таблицу (также избегайте ужасного поведения блокировки SqlBulkCopy), затем MERGE в финальную таблицу с правильными правилами.
Простой, сделанный, вот как я делаю все мои массовые обновления.