3

この質問は以前に尋ねられました...しかし、私が探している正確な答えを見つけることができないようです...私はたくさんのレコードを挿入し、挿入されたID値を取り戻す必要があります...私はやっていますこれ:

INSERT MyTable(col1, ....)
OUTPUT inserted.IdentityColumn
SELECT p.i.value('@XmlAttribute', 'nvarchar(128)') FROM @myXml.nodes('/root/i') AS p(i)

これは正常に動作します...

更新可能なサブスクリプションを使用してSQLトランザクションレプリケーションを入力します。これにより、サブスクライバーのレプリケートされたテーブルにトリガーが配置されます。

このシナリオでは、OUTPUTは機能しなくなります。

だから、私は今これをやっています...しかし、私はこれについて私の腸に悪い気持ちを持っており、私は並行性の問題への扉を開いたと思います(私は前向きではありませんが)。

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE  
DECLARE @currentIdentity bigint
SET @currentIdentity = SELECT IDENT_CURRENT('MyTable') + 1
...
SELECT IdentityColumn FROM MyTable WHERE IdentityColumn <= IDENT_CURRENT('MyTable') AND IdentityColumn >= @currentIdentity

提案?生成された一意の識別子に対してこのアプローチが機能しないため、これも悪臭を放ちます。

4

1 に答える 1

4

OUTPUTテーブル変数に挿入するバリアントを使用できます。ドキュメントから:

INTO キーワードを指定せずに OUTPUT 句を指定した場合、DML 操作のターゲットには、特定の DML アクションに対して有効なトリガーを定義することはできません。たとえば、UPDATE ステートメントで OUTPUT 句が定義されている場合、ターゲット テーブルで有効な UPDATE トリガーを使用することはできません。

(強調を追加)

したがって、次のことができます。

DECLARE @IDs table (ID int not null)
INSERT MyTable(col1, ....)
OUTPUT inserted.IdentityColumn INTO @IDs
SELECT p.i.value('@XmlAttribute', 'nvarchar(128)') FROM @myXml.nodes('/root/i') AS p(i)

SELECT * from @IDs

行数メッセージなどを処理していない限り、元の動作とほぼ同じ動作になります。

于 2013-01-02T07:25:30.460 に答える