I think other answers given may be more practical, but I did want to record my finding here in case it helps someone some day. (This is in SQL Server 2005; not sure whether this behavior persists in newer versions.)
The basis of the trick is an exploitation of the following property (from Books Online's documentation of @@IDENTITY
): "After an INSERT, SELECT INTO, or bulk copy statement is completed . . . If the statement did not affect any tables with identity columns, @@IDENTITY returns NULL." Although I can't find it explicitly stated, it appears that this behavior applies to SCOPE_IDENTITY()
as well. So, we complete an INSERT
statement that does not affect any tables with identity columns:
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!
So, for your case, it would seem that you could do
INSERT INTO NoIdentity (notId)
SELECT 0
WHERE 1 = 0
to reset SCOPE_IDENTITY()
before performing your second INSERT
.