Tôi đang cố gắng cập nhật một bảng với một loạt các giá trị. Mỗi mục trong mảng chứa thông tin khớp với một hàng trong bảng trong cơ sở dữ liệu SQL Server. Nếu hàng đã tồn tại trong bảng, chúng tôi cập nhật hàng đó với thông tin trong mảng đã cho. Khác, chúng tôi chèn một hàng mới trong bảng. Về cơ bản tôi đã mô tả upert.
Bây giờ, tôi đang cố gắng đạt được điều này trong một thủ tục được lưu trữ có tham số XML. Lý do tôi đang sử dụng XML và không phải là tham số có giá trị bảng là vì, sau này, tôi sẽ phải tạo loại tùy chỉnh trong SQL và liên kết loại này với thủ tục được lưu trữ. Nếu tôi từng thay đổi một cái gì đó trong thủ tục được lưu trữ hoặc lược đồ db của tôi trên đường, tôi sẽ phải làm lại cả thủ tục được lưu trữ và loại tùy chỉnh. Tôi muốn tránh tình trạng này. Ngoài ra, tính ưu việt của TVP so với XML không hữu ích cho trường hợp của tôi bởi vì, kích thước mảng dữ liệu của tôi sẽ không bao giờ vượt quá 1000. Điều này có nghĩa là tôi không thể sử dụng giải pháp được đề xuất ở đây: Cách chèn nhiều bản ghi bằng XML trong máy chủ SQL 2008
Ngoài ra, một cuộc thảo luận tương tự ở đây ( UPSERT - Có cách nào khác thay thế cho MERGE hoặc @@ rowcount không? ) Khác với những gì tôi đang hỏi bởi vì, tôi đang cố gắng đưa nhiều hàng vào một bảng.
Tôi đã hy vọng rằng tôi chỉ đơn giản sẽ sử dụng bộ truy vấn sau đây để tăng giá trị từ xml. Nhưng điều này sẽ không làm việc. Cách tiếp cận này chỉ được cho là hoạt động khi đầu vào là một hàng đơn.
begin tran
update table with (serializable) set select * from xml_param
where key = @key
if @@rowcount = 0
begin
insert table (key, ...) values (@key,..)
end
commit tran
Thay thế tiếp theo là sử dụng một EXISTS đầy đủ hoặc một trong các biến thể của hình thức sau đây. Nhưng, tôi từ chối điều này trên cơ sở hiệu quả dưới mức tối ưu:
IF (SELECT COUNT ... ) > 0
UPDATE
ELSE
INSERT
Tùy chọn tiếp theo là sử dụng câu lệnh Hợp nhất như được mô tả ở đây: http://www.databasejournal.com/features/mssql/USE-the-merge-statement-to-perform-an-upsert.html . Nhưng, sau đó tôi đọc về các vấn đề với truy vấn Hợp nhất tại đây: http://www.mssqltips.com/sqlservertip/3074/use-caestion-with-sql-servers-merge-statement/ . Vì lý do này, tôi đang cố gắng tránh Hợp nhất.
Vì vậy, bây giờ câu hỏi của tôi là: có bất kỳ tùy chọn nào khác hoặc cách tốt hơn để đạt được nhiều lần sử dụng tham số XML trong thủ tục lưu trữ SQL Server 2008 không?
Xin lưu ý rằng dữ liệu trong tham số XML có thể chứa một số bản ghi không được lưu trữ do cũ hơn bản ghi hiện tại. Có một ModifiedDate
trường trong cả XML và bảng đích cần được so sánh để xác định xem bản ghi sẽ được cập nhật hay loại bỏ.
MERGE
mà Bertrand chỉ ra hầu hết là các trường hợp cạnh và không hiệu quả, không hiển thị các nút chặn - MS sẽ không phát hành nó nếu đó là một bãi mìn thực sự. Bạn có chắc chắn rằng các kết quả bạn đang trải qua để tránh MERGE
không tạo ra nhiều lỗi tiềm ẩn hơn là chúng đang lưu không?
MERGE
. Các bước CHERTN và CẬP NHẬT của MERGE vẫn được xử lý riêng. Sự khác biệt chính trong cách tiếp cận của tôi là biến bảng chứa ID bản ghi được cập nhật và truy vấn XÓA sử dụng biến bảng đó để xóa các bản ghi đó khỏi bảng tạm thời của dữ liệu đến. Và tôi cho rằng NGUỒN có thể được chuyển trực tiếp từ @ XMLparam.nodes () thay vì đổ vào bảng tạm thời, nhưng vẫn không có nhiều thứ để bạn không phải lo lắng về việc gặp phải một trong những trường hợp cạnh đó; - ).