[解決済み] SQL Server の Insert Update ストアド プロシージャ
質問
私は、レコードが存在する場合は更新を行い、そうでない場合は挿入を行うストアド プロシージャを書きました。それは次のようなものです。
update myTable set Col1=@col1, Col2=@col2 where ID=@ID
if @@rowcount = 0
insert into myTable (Col1, Col2) values (@col1, @col2)
このように記述する背後にある私の論理は、更新がwhere句を使用して暗黙のselectを実行し、それが0を返したら挿入が実行されるというものです。
この方法の代替案は、select を実行し、返された行の数に基づいて更新または挿入を実行することです。更新を行う場合、2 つの選択 (最初の明示的な選択呼び出しと更新の場所での 2 番目の暗黙的な呼び出し) が発生するため、これは非効率的であると考えました。もし、procが挿入を行うのであれば、効率に違いはないでしょう。
私のロジックはここで正しいですか? これは、ストアド プロシージャに挿入と更新を結合する方法ですか?
どのように解決するのですか?
あなたの仮定は正しいです。これは最適な方法で、次のように呼ばれます。 upsert/merge .
UPSERTの重要性 - sqlservercentral.comより :
<ブロッククオート上記のケースで更新されるたびに、私たちはテーブルから1つの追加の読み取りを削除しています。 テーブルから追加の読み取りを削除していることになります。 の代わりに UPSERT を使用する場合、テーブルから 1 回の読み取りを削除することになります。 残念ながら、挿入の場合、UPSERTとIF EXISTSの両方のメソッドは UPSERT と IF EXISTS の両方のメソッドは、テーブル上で同じ数の読み取りを使用します。 Insertの場合、UPSERTとIF EXISTSの両方のメソッドがテーブル上で同じ数の読み取りを行う。 したがって、存在チェックは を正当化する正当な理由がある場合にのみ実行されるべきです。 存在チェックは、追加I/Oを正当化する非常に有効な理由がある場合にのみ行われるべきです。 存在チェックは、追加のI/Oを正当化する非常に正当な理由がある場合にのみ行われるべきです。最適化された方法は 最適な方法は をできるだけ少なくすることです。 DBにできるだけ読み込まないようにすることです。
を試みることが最良の戦略です。 の更新を試みることです。更新によって影響を受ける行がない場合 を挿入します。ほとんどの場合 行はすでに存在し、1回のI/Oで済みます。 存在し、必要なI/Oは1回だけです。 が必要です。
Edit : をご覧ください。 この回答 とリンクしているブログ記事で、このパターンの問題点と安全に動作させる方法について学んでください。
関連
-
[解決済み] SQL ServerでSELECTからUPDATEする方法とは?
-
[解決済み] SQL Server で複数行のテキストを 1 つのテキスト文字列に連結する方法
-
[解決済み] SQL Server の DateTime データ型から日付だけを返す方法
-
[解決済み] SQL ServerでJOINを使用してUPDATE文を実行するにはどうすればよいですか?
-
[解決済み] SQLのIN句をパラメータ化する
-
[解決済み] SQL Serverでストアドプロシージャ内のテキストを検索する
-
[解決済み] SQL Serverにおける関数とストアドプロシージャの比較
-
[解決済み] SQL ServerにおけるINSERT OR UPDATEに関する解決策
-
[解決済み] SQLite - UPSERT *not* INSERT or REPLACE
-
[解決済み】SQL Serverで既存のテーブルにデフォルト値を持つカラムを追加する
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
windows mysql prompt access denied for user ''@'localhost' to database.
-
org.postgresql.util.PSQLException: ERROR: リレーション "userinfo" の列 "loginid" が存在しません。
-
[解決済み] Oracleの全テーブルのリストを取得しますか?
-
[解決済み] SQL Serverでテーブルからカラム名を取得するにはどうすればよいですか?
-
[解決済み] SQL Server における DateTime2 と DateTime の比較
-
[解決済み] SQL ServerにおけるINSERT OR UPDATEに関する解決策
-
[解決済み] SQLite - UPSERT *not* INSERT or REPLACE
-
[解決済み] 複数の列に対してSELECT DISTINCTする方法(またはできる方法)は?
-
[解決済み] Entity Framework VS LINQ to SQL VS ADO.NETでストアドプロシージャを使う?[クローズド]
-
[解決済み] Postgres でサブクエリを使用してテーブルの行を更新する