когда в исходной таблице есть повторяющиеся строки. Хорошее решение. Спасибо, что поделился.
аюсь вставить много записей, используя инструкцию MERGE в T-SQL, но мой запрос не может выполнить INSERT, если в исходной таблице есть повторяющиеся записи. Ошибка вызвана:
Таблица назначения имеет первичный ключ на основе двух столбцовИсходная таблица может содержать дубликаты записей, которые нарушают ограничение первичного ключа целевой таблицы (выбрасывается «Нарушение ограничения PRIMARY KEY»)Я ищу способ изменить мой оператор MERGE так, чтобы он либо игнорировал дублирующиеся записи в исходной таблице, и / или пытался / ловил оператор INSERT, чтобы перехватывать возможные исключения (т.е. все другие операторы INSERT будут выполняться независимо от может появиться несколько плохих яиц) - или, может быть, есть лучший способ решить эту проблему?
Вот пример запроса того, что я пытаюсь объяснить. В следующем примере мы добавим 100 тыс. Записей во временную таблицу, а затем попытаемся вставить эти записи в целевую таблицу.
РЕДАКТИРОВАТЬ В своем исходном сообщении я включил только два поля в таблицы примеров, которые дали SO друзьям возможность предложить решение DISTINCT, чтобы избежать дублирования в операторе MERGE. Я должен был упомянуть, что в моей реальной задаче таблицы имеют 15 полей, и из этих 15 два поля представляют собой КЛАСТЕРНЫЙ ПЕРВИЧНЫЙ КЛЮЧ. Так что ключевое слово DISTINCT не работает, потому что мне нужно выбрать все 15 полей и игнорировать дубликаты на основе двух полей.
Я обновил запрос ниже, чтобы включить еще одно поле, col4. Мне нужно включить col4 в MERGE, но мне нужно только убедиться, что ТОЛЬКО col2 и col3 уникальны.
-- Create the source table
CREATE TABLE #tmp (
col2 datetime NOT NULL,
col3 int NOT NULL,
col4 int
)
GO
-- Add a bunch of test data to the source table
-- For testing purposes, allow duplicate records to be added to this table
DECLARE @loopCount int = 100000
DECLARE @loopCounter int = 0
DECLARE @randDateOffset int
DECLARE @col2 datetime
DECLARE @col3 int
DECLARE @col4 int
WHILE (@loopCounter) < @loopCount
BEGIN
SET @randDateOffset = RAND() * 100000
SET @col2 = DATEADD(MI,@randDateOffset,GETDATE())
SET @col3 = RAND() * 1000
SET @col4 = RAND() * 10
INSERT INTO #tmp
(col2,col3,col4)
VALUES
(@col2,@col3,@col4);
SET @loopCounter = @loopCounter + 1
END
-- Insert the source data into the target table
-- How do we make sure we don't attempt to INSERT a duplicate record? Or how can we
-- catch exceptions? Or?
MERGE INTO dbo.tbl1 AS tbl
USING (SELECT * FROM #tmp) AS src
ON (tbl.col2 = src.col2 AND tbl.col3 = src.col3)
WHEN NOT MATCHED THEN
INSERT (col2,col3,col4)
VALUES (src.col2,src.col3,src.col4);
GO