我倾向于回避代理键,转而使用自然键或 FK;另外,我会避免IDENTITY
使用人工标识符。老实说,我发现自己是少数,并且经常想知道如何使用IDENTITY
FK 实现批量插入。
根据 Alan Barker 的回答,您可以使用SCOPE_IDENTITY()
,但前提是您想要执行此 RBAR(逐行排列)。你说,“这是一个清理操作”,所以也许一个程序解决方案是可以接受的。
我自己解决这个问题的方法是手动生成一系列潜在IDENTITY
值(例如在临时表中),然后SET IDENTITY_INSERT TargetTable ON
用来强制输入这些值。显然,我需要确保建议的值实际上不会被使用发生的时间,INSERT
因此仍然需要阻止所有其他用户。
有几件事要看。有时缺少列上的强制性UNIQUE
约束,IDENTITY
因此您可能需要自己检查是否有冲突。此外,我发现当值不是连续的(并且在正范围内!)或者更糟糕的是,存在依赖于完美的应用程序逻辑时,喜欢代理的人可能会有点“慌乱”序列或已将值暴露 IDENTITY
给业务(在这种情况下,“伪造”企业关键值(例如订单号)可能会成为现实生活中审计员的家常便饭)。
编辑:今天早上阅读另一个 SO 问题的答案让我想起了 SQL Server 2008 的OUTPUT
子句来捕获表中所有自动生成的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