Я думаю, что другие ответы могут быть более практичными, но я действительно хотел записать свои результаты здесь, на случай, если они кому-нибудь помогут. (Это в SQL Server 2005; не уверен, сохраняется ли это поведение в более новых версиях.)
В основе этого трюка лежит использование следующего свойства (из документации @@IDENTITY
в Books Online): «После выполнения оператора INSERT, SELECT INTO или массового копирования ... Если это заявление не повлияло ни на какое в таблицах со столбцами идентификаторов @@ IDENTITY возвращает NULL. " Хотя я не могу найти это в явном виде, похоже, что это поведение относится и к SCOPE_IDENTITY()
. Итак, мы завершим оператор INSERT
, который не влияет ни на одну таблицу со столбцами идентификаторов:
CREATE TABLE NoIdentity (notId BIT NOT NULL)
-- An insert that actually inserts sets SCOPE_IDENTITY():
INSERT INTO YourTable (name)
SELECT 'a'
WHERE 1 = 1 -- simulate a join that yields rows
SELECT @@identity, SCOPE_IDENTITY()
-- 14, 14 (or similar)
-- The problem: an insert that doesn't insert any rows leaves SCOPE_IDENTITY() alone.
INSERT INTO YourTable (name)
SELECT 'a'
WHERE 1 = 0 -- simulate a join that yields no rows
SELECT @@identity, SCOPE_IDENTITY()
-- Still 14, 14 . . . how do we know we didn't insert any rows?
-- Now for the trick:
INSERT INTO NoIdentity (notId)
SELECT 0
WHERE 1 = 0 -- we don't actually need to insert any rows for this to work
SELECT @@identity, SCOPE_IDENTITY()
-- NULL, NULL. Magic!
INSERT INTO YourTable (name)
SELECT 'a'
WHERE 1 = 0 -- simulate a join that yields no rows
SELECT @@identity, SCOPE_IDENTITY()
-- Still NULL, NULL since we didn't insert anything. But if we had, it would be non-NULL.
-- We can tell the difference!
Итак, для вашего случая может показаться, что вы могли бы
INSERT INTO NoIdentity (notId)
SELECT 0
WHERE 1 = 0
для сброса SCOPE_IDENTITY()
перед выполнением второго INSERT
.