UPSERT - Có sự thay thế nào tốt hơn cho MERGE hoặc @@ rowcount không? [đóng cửa]


14

Tôi đã tự hỏi nếu bạn đã gặp một lệnh T-SQL tương tự như khái niệm về UPSERT? Việc thực hiện các thao tác INSERT | UPDATE bằng các tùy chọn (1) hoặc (2) dường như quá phức tạp và dễ bị lỗi.

MỤC TIÊU

Để đảm bảo rằng bản ghi mong muốn (trong trường hợp này là worker_id 1) được cập nhật mà KHÔNG cần phải viết cùng một truy vấn hai lần.

BỐI CẢNH

  • tên bảng: nhân viên
  • id nhân viên: có khóa chính và proerty nhận dạng được đặt thành đúng

LỰA CHỌN

  1. thực thi SQL CẬP NHẬT ... kiểm tra @@ rowcount = 0 và @@ error = 0 ... thực thi SQL INSERT nếu được yêu cầu

    • con: bạn thực sự phải viết cùng một truy vấn hai lần, một lần như một lần chèn, một lần như một lần cập nhật
    • con: thêm mã = ​​thêm thời gian gõ
    • con: thêm mã = ​​nhiều chỗ hơn cho lỗi

/programming/1106717/how-to-im vây-a-điều kiện-upsert-stored-products "Cập nhật bằng cách sử dụng @@ rowcount"

  1. thực thi SQL MERGE
    • con: bạn thực sự phải viết cùng một truy vấn hai lần, một lần như một lần chèn, một lần như một lần cập nhật
    • con: thêm mã = ​​thêm thời gian gõ
    • con: thêm mã = ​​nhiều chỗ hơn cho lỗi

http://technet.microsoft.com/en-us/l Library / bb510625.aspx "Hợp nhất T-SQL"

  1. thực thi SQL UPSERT (tính năng không tồn tại)
    • pro: bạn xác định mối quan hệ dữ liệu với bảng một lần (hãy để SQL Server lo lắng về việc đó có phải là CHERTN hay CẬP NHẬT)
    • pro: ít mã = ​​thực hiện nhanh hơn
    • pro: ít mã = ​​xác suất thấp hơn

VÍ DỤ

Nhân viên của UPSERT (worker_id, worker_number, job_title, First_name, middle_name, họ, đã sửa đổi_at)

  • nếu worker_id 1 không tồn tại: MS SQL thực thi câu lệnh INSERT
  • if worker_id 1 tồn tại: MS SQL thực thi và câu lệnh CẬP NHẬT

4
Đây có vẻ như là một yêu cầu tính năng cho Microsoft, không phải ai đó ở đây cũng có thể giúp bạn giải quyết. Giải pháp mà Microsoft đưa ra là MERGE. Nếu điều đó không đủ linh hoạt / đủ mạnh cho bạn, thì bạn cần một giải pháp khác chưa tồn tại.
Aaron Bertrand

3
Theo tôi, MERGEđơn giản, linh hoạt và nó cũng là một phần của Tiêu chuẩn SQL. Vấn đề thực sự với MERGEvà các UPSERTtriển khai khác là leo thang khóa tiềm năng hoặc thậm chí là bế tắc không liên quan gì đến cú pháp.
a1ex07

Nếu bạn có một câu hỏi, hãy hỏi nó. Như đã viết, đây về cơ bản là một diatribe về MERGEviệc triển khai trong SQL Server.
JNK

Câu hỏi hay - về cơ bản là có một tuyên bố UPSERT mà máy chủ lo lắng về việc liệu nó có yêu cầu chèn hoặc cập nhật hay không. Tôi đồng ý, MERGE không đáp ứng những gì bạn mong đợi một cách hợp lý về việc triển khai "UPSERT". Do MS đã chọn thực hiện theo cách này, câu hỏi của tôi sẽ là: điều gì có thể là thiếu sót hoặc không thể thực hiện được, liệu họ đã cố gắng thực hiện cú pháp mà bạn (và tôi) muốn như thế nào?
youcantryreachingme

Câu trả lời:


14

Tôi nghĩ rằng câu trả lời đơn giản cho điều này là không. MERGElà câu trả lời của Microsoft cho UPSERTlogic phức tạp hơn . Và bạn thậm chí không liệt kê cách tiếp cận tồi tệ nhất:

IF (SELECT COUNT ... ) > 0
    UPDATE
ELSE
    INSERT

Tôi vừa ngậm trong miệng một chút, nhưng đó thực sự là thứ tôi thấy thường xuyên nhất.

Trong mọi trường hợp, nếu MERGEkhông đủ linh hoạt hoặc đủ mạnh cho bạn, tôi khuyên bạn nên gửi yêu cầu tính năng cho Microsoft tại http://connect.microsoft.com/sql/ và giải thích cặn kẽ, trường hợp kinh doanh của bạn. Miễn là bạn tuân thủ các lợi thế thực sự của cú pháp được đề xuất của bạn MERGE, bạn đã nhận được phiếu bầu của tôi. Nếu bạn treo quá nhiều vào phần "dễ bị lỗi", tôi không có khả năng mua. Tại sao? Bởi vì bạn có thể béo ngón tay bất kỳ tuyên bố.

Điều đó nói rằng, tôi không nghĩ rằng bất cứ ai ở đây có thể làm cho bạn cụ thể. Bạn nên điều tra các vấn đề tiềm ẩn với MERGE:

http://www.mssqltips.com/sqlservertip/3074/use-caestion-with-sql-servers-merge-statement/


2
Cảm ơn Aaron. Tôi đã xem qua tài liệu T-SQL trên MSDN và không thể tìm thấy những gì tôi đang tìm kiếm; chỉ cần nghĩ rằng tôi sẽ ném nó ra khỏi đó trong trường hợp tôi bỏ lỡ một cái gì đó. Mặc dù tuyên bố MERGE có ý nghĩa trong một số tình huống nhất định, tôi không thể không cảm thấy rằng đó là một giải pháp "búa tạ để đập vào móng tay" cho một hoạt động tiết kiệm đơn giản. Có lẽ tôi nên lấy chiếc mũ lập trình viên của mình và đeo chiếc DBA Fedora của mình. Cảm ơn bạn đã dành thời gian để chia sẻ suy nghĩ của bạn.
Pressacco
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.