Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

CẬP NHẬT nếu tồn tại CHÈN khác trong SQL Server 2008

Nhiều người sẽ đề xuất bạn sử dụng MERGE , nhưng tôi cảnh báo bạn chống lại nó. Theo mặc định, nó không bảo vệ bạn khỏi các điều kiện đồng thời và chủng tộc hơn nhiều câu lệnh, nhưng nó gây ra các mối nguy hiểm khác:

  • Thận trọng với Câu lệnh MERGE của SQL Server
  • Điều gì cần tránh nếu bạn muốn sử dụng MERGE
  • Các mẫu và phản phân tử của SQL Server UPSERT

Ngay cả khi có sẵn cú pháp "đơn giản hơn" này, tôi vẫn thích cách tiếp cận này hơn (bỏ qua xử lý lỗi cho ngắn gọn):

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
UPDATE dbo.table SET ... WHERE PK = @PK;
IF @@ROWCOUNT = 0
BEGIN
  INSERT dbo.table(PK, ...) SELECT @PK, ...;
END
COMMIT TRANSACTION;

Thông tin thêm về UPSERT này tiếp cận ở đây:

  • Vui lòng ngừng sử dụng chống mẫu UPSERT này

Nhiều người sẽ gợi ý cách này:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
IF EXISTS (SELECT 1 FROM dbo.table WHERE PK = @PK)
BEGIN
  UPDATE ...
END
ELSE
BEGIN
  INSERT ...
END
COMMIT TRANSACTION;

Nhưng tất cả những thành tựu này là đảm bảo rằng bạn có thể cần đọc bảng hai lần để xác định (các) hàng sẽ được cập nhật. Trong mẫu đầu tiên, bạn sẽ chỉ cần xác định (các) hàng một lần. (Trong cả hai trường hợp, nếu không có hàng nào được tìm thấy từ lần đọc ban đầu, thì một lần chèn sẽ xảy ra.)

Những người khác sẽ đề xuất theo cách này:

BEGIN TRY
  INSERT ...
END TRY
BEGIN CATCH
  IF ERROR_NUMBER() = 2627
    UPDATE ...
END CATCH

Tuy nhiên, điều này là có vấn đề nếu không có lý do nào khác ngoài việc để SQL Server bắt các ngoại lệ mà bạn có thể đã ngăn chặn ngay từ đầu sẽ đắt hơn nhiều, ngoại trừ trường hợp hiếm hoi mà hầu như mọi lần chèn đều không thành công. Tôi chứng minh càng nhiều ở đây:

  • Kiểm tra các vi phạm ràng buộc tiềm ẩn trước khi tham gia TRY / CATCH
  • Tác động đến hiệu suất của các kỹ thuật xử lý lỗi khác nhau

Không chắc bạn nghĩ mình đạt được gì khi có một tuyên bố duy nhất; Tôi không nghĩ rằng bạn đạt được bất cứ điều gì. MERGE là một câu lệnh duy nhất nhưng dù sao nó vẫn phải thực sự thực hiện nhiều thao tác - ngay cả khi nó khiến bạn nghĩ rằng nó không.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Trả lại tất cả các cột không được tính toán từ một bảng trong SQL Server

  2. Cách bật Tất cả Ràng buộc Kiểm tra &Khóa ngoại cho Bảng trong SQL Server (Ví dụ T-SQL)

  3. Nhận cảnh báo:Giá trị rỗng bị loại bỏ bởi hoạt động tổng hợp hoặc SET khác

  4. Chèn ảnh vào trường ảnh SQL Server 2005 chỉ sử dụng SQL

  5. Cách nhanh nhất để liệt kê tất cả cơ sở dữ liệu trong SQL Server bằng T-SQL