Я склонен избегать суррогатных ключей в пользу натуральных ключей или ФК;также, я бы избегал IDENTITY
для искусственных идентификаторов.Честно говоря, я нахожусь в меньшинстве и часто задавался вопросом, как добиться массовых вставок с IDENTITY
ФК.
Согласно ответу Алана Баркера, вы можете использовать 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