Myślę inne odpowiedzi udzielone może być bardziej praktyczne, ale ja chciałem nagrać moje odkrycie tutaj w przypadku pomaga ktoś kiedyś. (Jest to w SQL Server 2005, nie ma pewności, czy to zachowanie będzie występować w nowszych wersjach.)
Podstawą triku jest wykorzystanie następującej właściwości (z dokumentacji Books Online z @@IDENTITY
): "Po INSERT, WYBIERZ Instrukcja INTO lub zbiorczego kopiowania została zakończona ... Jeśli instrukcja nie wpłynęła na tabele z kolumnami tożsamości, @@ IDENTITY zwraca NULL. " Chociaż nie mogę znaleźć tego wprost, wydaje się, że to zachowanie dotyczy również SCOPE_IDENTITY()
. Więc wypełnić oświadczenie INSERT
że nie narusza żadnych tabel z kolumnami tożsamości:
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!
tak, w Twoim przypadku, wydaje się, że można zrobić
INSERT INTO NoIdentity (notId)
SELECT 0
WHERE 1 = 0
zresetować SCOPE_IDENTITY()
przed wykonaniem swojej drugi INSERT
.