私は、自然キーまたは FK を優先して代理キーを避ける傾向があります。IDENTITY
また、人工的な識別子は避けます。正直なところ、私は少数派であり、FK を使用して一括挿入を行う方法について疑問に思っていIDENTITY
ました。
Alan Barkerの回答によると、SCOPE_IDENTITY()
このRBARを実行したい場合にのみ利用できます(行を苦しめます)。「これはクリーンアップ操作です」とあなたは言うので、おそらく手続き的な解決策が受け入れられます。
私が自分で問題を回避した方法は、潜在的なIDENTITY
値のシーケンスを手動で生成し (たとえば、ステージング テーブルで) SET IDENTITY_INSERT TargetTable ON
、値を強制的に使用することです。明らかに、提案された値が実際に使用されないようにする必要があります。他のINSERT
すべてのユーザーを引き続きブロックする必要があります。
注目すべき点がいくつかあります。列の必須のUNIQUE
制約IDENTITY
が欠落している場合があるため、衝突がないことを自分で確認する必要がある場合があります。また、サロゲートが好きな人は、値がシーケンシャルでない (そして正の範囲にある!) 場合、またはさらに悪いことに、完全な値に依存するアプリケーション ロジックがある場合、少し「混乱」する可能性があることを発見しました。シーケンスまたは IDENTITY
値をビジネスに公開しました (この場合、注文番号などの「偽造」エンタープライズ キー値は、実際の監査人に狙われる可能性があります)。
編集: 今朝別の SO の質問への回答を読んで、テーブル内のOUTPUT
すべての自動生成された値をキャプチャする SQL Server 2008 の句について思い出しました。IDENTITY
CREATE TABLE #InsertedBooks
(
ID INTEGER NOT NULL UNIQUE, -- surrogate
isbn_13 CHAR(13) NOT NULL UNIQUE -- natural key
);
WITH InsertingBooks (isbn_13)
AS
(
SELECT '9781590597453'
UNION ALL
SELECT '9780596523060'
UNION ALL
SELECT '9780192801425'
)
INSERT INTO Books (isbn_13)
OUTPUT inserted.ID, inserted.isbn_13 -- <--
INTO #InsertedBooks (ID, isbn_13) -- <--
SELECT isbn_13
FROM InsertingBooks;
INSERT INTO AnotherTable...
SELECT T1.ID, ...
FROM #InsertedBooks AS T1...;
DROP TABLE #InsertedBooks