Tôi đang cố gắng chèn nhiều bản ghi bằng cách sử dụng câu lệnh MERGE của T-SQL, nhưng truy vấn của tôi không INSERT khi có bản ghi trùng lặp trong bảng nguồn. Sự thất bại là do:Cách tránh chèn bản ghi trùng lặp khi sử dụng câu lệnh T-SQL Merge
- Bảng mục tiêu có một Primary Key dựa trên hai cột
- các bảng nguồn có thể chứa dữ liệu trùng vi phạm chế Primary Key bảng mục tiêu ("Vi phạm các hạn chế PRIMARY KEY" là ném)
Tôi đang tìm cách thay đổi câu lệnh MERGE để bỏ qua các bản ghi trùng lặp trong bảng nguồn và/hoặc sẽ thử/nắm bắt câu lệnh INSERT để bắt ngoại lệ có thể xảy ra (nghĩa là tất cả các câu lệnh INSERT khác sẽ chạy bất kể vài quả trứng xấu có thể xảy ra) - hoặc, có thể, có một cách tốt hơn o đi về vấn đề này?
Dưới đây là ví dụ truy vấn về những gì tôi đang cố giải thích. Ví dụ dưới đây sẽ thêm 100k hồ sơ vào một bảng tạm thời và sau đó sẽ cố gắng để chèn những bản ghi trong bảng mục tiêu -
EDIT Trong bài ban đầu của tôi tôi chỉ bao gồm hai trường trong bảng ví dụ mà nhường chỗ cho SO bạn bè để đưa ra giải pháp DISTINCT để tránh trùng lặp trong tuyên bố MERGE. Tôi cần phải đề cập rằng trong vấn đề thực tế của tôi, các bảng có 15 trường và 15 trường, hai trong số các trường là một khóa CHÍNH XÁC ĐÁP. Vì vậy, từ khóa DISTINCT không hoạt động vì tôi cần phải SELECT tất cả 15 trường và bỏ qua các bản sao dựa trên hai trường.
Tôi đã cập nhật truy vấn bên dưới để bao gồm một trường nữa, col4. Tôi cần phải bao gồm col4 trong MERGE, nhưng tôi chỉ cần chắc chắn rằng chỉ col2 và col3 là duy nhất.
-- 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
Bạn phải quyết định hàng nào bạn nên chọn col4 từ khi có các bản sao cho col2 và col3 trong #tmp. Ví dụ, bạn có thể sử dụng 'nhóm bằng col2, col3' và' min (col4) làm col4'. –