web-dev-qa-db-ja.com

UPSERT-MERGEまたは@@ rowcountのより良い代替手段はありますか?

UPSERTの概念に似たT-SQLコマンドに遭遇したのかどうか疑問に思いましたか?オプション(1)または(2)を使用してINSERT | UPDATE操作を実行すると、非常に複雑になり、エラーが発生しやすくなります。

[〜#〜]目的[〜#〜]

目的のレコード(この場合、employee_id 1)が最新であることを確認するには、基本的に同じクエリを2回書き込む必要はありません。

[〜#〜]コンテキスト[〜#〜]

  • テーブル名:従業員
  • 従業員ID:主キーがあり、IDプロパティがtrueに設定されています

[〜#〜]オプション[〜#〜]

  1. sQL UPDATEを実行... @@ rowcount = 0および@@ error = 0を確認...必要に応じてSQL INSERTを実行

    • con:事実上、同じクエリを2回(1回は挿入、1回は更新として)記述する必要があります
    • con:より多くのコード=より多くの時間入力
    • con:より多くのコード=エラーの余地

https://stackoverflow.com/questions/1106717/how-to-implement-a-conditional-upsert-stored-procedure "@@ rowcountを使用して更新"

  1. sQL MERGE を実行します
    • con:事実上、同じクエリを2回(1回は挿入、1回は更新として)記述する必要があります
    • con:より多くのコード=より多くの時間入力
    • con:より多くのコード=エラーの余地

http://technet.Microsoft.com/en-us/library/bb510625.aspx "T-SQL Merge"

  1. sQL UPSERTを実行します(機能は存在しません)
    • プロ:データとテーブルの関係を1回定義します(SQL ServerがINSERTかUPDATEかを心配します)
    • プロ:少ないコード=より速い実装
    • プロ:コードが少ない=確率が低い

アップサートの例

UPSERT従業員(employee_id、employee_number、job_title、first_name、middle_name、surname、modified_at)VALUES(1、'00 -124AB37 '、' Manager '、' John '、' T '、' Smith '、GetDate());

  • employee_id 1が存在しない場合:MS SQLはINSERTステートメントを実行します
  • employee_id 1が存在する場合:MS SQLが実行され、UPDATEステートメント
14
Pressacco

これに対する簡単な答えはノーだと思います。 MERGEは、より複雑なUPSERTロジックに対するMicrosoftの回答でした。そして、あなたは最悪のアプローチすらリストしませんでした:

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

少しタイプして口に放り込んだだけですが、実際によく目にするものです。

いずれにせよ、MERGEが柔軟性がなく、強力でもない場合は、機能リクエストをMicrosoftに http://connect.Microsoft.com/sql/ で送信することをお勧めします。ビジネスケースを完全に説明してください。 MERGEよりも提案された構文の真の利点に固執する限り、あなたは私の票を得ました。 「エラーが発生しやすい」部分にこだわりすぎていると、私は買いそうにありません。なぜですか?あなたはどんな声明でも太ることができるからです。

とは言っても、ここであなたのために特別にできることはないと思います。 MERGEの潜在的な問題を調査する必要があります:

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

14
Aaron Bertrand