0

カスタムの自動インクリメント列である ID (identity) と XID (int) を持つテーブルがあります。XID を維持するために挿入トリガーの代わりに使用していますが、重複が発生しています。


テーブル

xtable (ID ID、XID int)


トリガー- 挿入の代わりに

insert into [xtable] (XID)
select [x].[NextavailableID]
from inserted [i]
cross apply
(
  select coalesce(max([t].[XID]), 0) + 1 [NextavailableID]
  from [xtable] [t]
) [x];

挿入 = 1 行と仮定します。

このトリガーは、XID 列の重複を防ぎません。それを変更する方法についてのアイデアはありますか?

4

2 に答える 2

2

問題は、複数の行が挿入されている場合、すべての行に同じ次の利用可能な ID を使用している場合ROW_NUMBER()、挿入で xid が一意であることを確認するために追加する必要があることです。

insert into [xtable] (XID)
select [x].[NextavailableID] + ROW_NUMBER() OVER (ORDER BY i.ID)
from inserted [i]
cross apply
(
  select coalesce(max([t].[XID]), 0) [NextavailableID]
  from [xtable] [t] WITH (TABLOCK, HOLDLOCK)
) [x];

重複の防止に関してxtableは、最大値を取得するときにテーブル ヒントを使用してロックできますxid

これらのロックを使用することの欠点は、デッドロックが発生することです。重複を防ぐため、この列に一意の制約/インデックスを設定する必要がありますが、競合条件が満たされた場合にも例外が発生します。最終的には、どの方法を選択するにしても、何らかの犠牲を払う必要があります。

于 2014-06-17T15:18:55.133 に答える