2

私は2つのテーブルを持っています。以下は、これらのテーブルの簡略版です。

TableA
Id <pk> incrementing
Name varchar(50)

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

これで、これらのテーブルは相互に関係があります。

シナリオ

ユーザー1が私のサイトにアクセスし、いくつかのアクションを実行します(この場合、テーブルAに行を追加します)。したがって、表AのすべてのデータをSqlBulkCopyを使用します。

ただし、テーブル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つのテーブルを処理するためのより良い方法はありますか?

4

3 に答える 3

3

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

ノート:

  • temptableは接続に対してローカルであり、分離されます

  • AとBへの書き込みはアトミックになります
  • 重複または後の書き込みは、後でAとBに何が起こるかを気にしません
  • 最後のポイントを強調すると、AとBは#temptableの行のセットからのみ入力されます

別:

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

于 2010-08-12T19:21:47.017 に答える
1

別の解決策と同じように、データベーストリガーを使用して2番目のテーブルを更新できます。

于 2010-08-12T19:41:33.770 に答える
1

1つのオプションは、SQLServerの出力句を使用することです。

INSERT YourTable (name)
OUTPUT INSERTED.*
VALUES ('NewName')

これid, nameにより、挿入された行がクライアントに返されるため、2番目のテーブルの挿入操作でそれらを使用できます。

于 2010-08-12T19:25:18.303 に答える