このストアドプロシージャの問題を解決する方法

sql sqlbulkcopy sql-server

質問

私は2つのテーブルを持っています。以下は、これらのテーブルの削除されたバージョンです。

TableA
Id <pk> incrementing
Name varchar(50)

TableB
TableAId <pk> non incrementing
Name varchar(50)

今、これらのテーブルはお互いに関係しています。

シナリオ

ユーザー1が私のサイトに来て、何らかのアクションを実行します(この場合、表Aに行が追加されます)。だから私はSqlBulkCopyを使用して、このすべてのデータを表Aに示します。

しかし、私はテーブルBにもデータを追加する必要がありますが、SQLBulkCopyがこれらを返さないため、テーブルAの新しく作成されたIDはわかりません。

だから私はテーブルBに存在しないし、それらを挿入するすべてのIDを見つけるストアドプロシージャを持つことを考えています。

INSERT INTO TableB (TableAId , Name)
SELECT Id,Name FROM TableA as tableA
WHERE not exists( ...)

しかし、これには問題があります。ユーザはいつでもTableBから何かを削除することができるので、ユーザが行を削除して別のユーザが来た場合でも、同じユーザであってもテーブルAに何かした場合でも、ストアドプロシージャはその削除された行を表Bに戻します。表Aではまだ存在するが、表Bでは存在しないため、ストアドプロシージャ条件を満たしているためです。

一括挿入を使用するときに更新する必要がある2つのテーブルを扱うより良い方法はありますか?

受け入れられた回答

SQLBulkCopyはこれを複雑にするので、ステージングテーブルとOUTPUT句の使用を検討したい

例:クライアントの擬似コードとSQ​​Lの混在

create SQLConnection

Create #temptable
Bulkcopy to #temptable

Call proc on same SQLConnection

proc:
   INSERT tableA (..)
   OUTPUT INSERTED.key, .. INTO TableB
   SELECT .. FROM #temptable

close connection

ノート:

  • 誘惑は接続に局所的であり、孤立している

  • AとBへの書き込みはアトミックになります
  • オーバーラップまたはそれ以降の書き込みは、後でAおよびBに何が起こるか気にしない
  • 最後のポイントを強調すると、AとBは#temptableの行セットからのみ読み込まれます

代替:

セッションIDと呼ばれるAとBに別の列を追加し、それを使用して行バッチを識別します。


人気のある回答

代わりのソリューションとして、 データベース・トリガーを使用して2番目の表を更新することもできます。



ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ