Giả sử bạn muốn có một thực tế SQL Server MERGE
tuyên bố:
MERGE INTO dbo.energydata WITH (HOLDLOCK) AS target
USING dbo.temp_energydata AS source
ON target.webmeterID = source.webmeterID
AND target.DateTime = source.DateTime
WHEN MATCHED THEN
UPDATE SET target.kWh = source.kWh
WHEN NOT MATCHED BY TARGET THEN
INSERT (webmeterID, DateTime, kWh)
VALUES (source.webmeterID, source.DateTime, source.kWh);
Nếu bạn cũng muốn xóa các bản ghi trong mục tiêu mà không phải là trong nguồn:
MERGE INTO dbo.energydata WITH (HOLDLOCK) AS target
USING dbo.temp_energydata AS source
ON target.webmeterID = source.webmeterID
AND target.DateTime = source.DateTime
WHEN MATCHED THEN
UPDATE SET target.kWh = source.kWh
WHEN NOT MATCHED BY TARGET THEN
INSERT (webmeterID, DateTime, kWh)
VALUES (source.webmeterID, source.DateTime, source.kWh)
WHEN NOT MATCHED BY SOURCE THEN
DELETE;
Bởi vì điều này đã trở thành một chút mor e phổ biến, tôi cảm thấy như tôi nên mở rộng câu trả lời này một chút với một số thông báo cần lưu ý.
Trước tiên, có một số blog báo cáo concurrency issues with the MERGE
statement. Điều này phần lớn có thể được làm việc xung quanh bằng cách xác định gợi ý HOLDLOCK
hoặc SERIALIZABLE
khóa:
MERGE INTO dbo.energydata WITH (HOLDLOCK) AS target
[...]
Bạn cũng có thể thực hiện điều tương tự với mức cô lập giao dịch hạn chế hơn.
Có several other known issues với MERGE
. Từ những gì tôi có thể nói, hầu hết trong số họ không phải là vấn đề phổ biến hoặc có thể được làm việc xung quanh với các gợi ý khóa như trên, nhưng tôi đã không thử nghiệm chúng.
Vì nó là, mặc dù tôi chưa bao giờ có bất kỳ vấn đề nào với tuyên bố MERGE
, tôi luôn sử dụng gợi ý WITH (HOLDLOCK)
ngay bây giờ và tôi chỉ muốn sử dụng câu lệnh trong trường hợp đơn giản nhất.
Có bản ghi nào trong 'temp_energydata' không có trong 'energydata' không? –