The documentation for SCOPE_IDENTITY states that it
Returns the last identity value inserted into an identity column in the same scope.
I wonder what last really means. Is it the largest value inserted in current scope, or the value of row that was physically last inserted into the table?
I tried to
- create table with
IDENTITYas a clustered index- this worked as expected; return value of
SCOPE_IDENTITYwas the highest value of identity column inserted
- this worked as expected; return value of
- create table with
IDENTITYas a column with different column as a cluster- i tried to use different
ORDER BYstatements to make sure that the generatedIDENTITYdidn't match the clustered index in any way SCOPE_IDENTITYalways returned the highest value ofIDENTITYcolumn reached, even though the identities were generated irrespectively of the clustered index
- i tried to use different
- I didn't try a heap table
Why I ask:
I stumbled upon a piece of code that inserts multiple rows and that uses SCOPE_IDENTITY to get the highest ID inserted, with which it then performs something. Given how SCOPE_IDENTITY seems to work, it currently works OK, but I wonder if it can bring in unexpected bugs.
My question is:
Should I alway assume that the SCOPE_IDENTITY returns the highest value of IDENTITY inserted (for ascending IDENTITY), no matter how the rows were either physically or logically inserted into the table? Or should I just use OUTPUT and than MAX on the identity column to be sure?
Edit: To put it into code, will following code always result in "This happens everytime", no matter what is in the CREATE TABLE #WithID, SELECT, FROM, WHERE or ORDER BY? Assuming the ID INTEGER IDENTITY(1,1) remains constant.
CREATE TABLE #WithID (ID INTEGER IDENTITY(1,1), SomeData INTEGER);
CREATE TABLE #Outputs (ID INTEGER);
INSERT INTO #WithID
OUTPUT Inserted.ID INTO #Outputs
SELECT Number
FROM dbo.Numbers
WHERE Number < 1000000
ORDER BY Number;
IF SCOPE_IDENTITY() = (SELECT MAX(ID) FROM #Outputs)
PRINT 'This happens everytime'
ELSE
PRINT 'Oops...';
note: I don't know how well known it is that the values created by IDENTITY are created in the order of the ORDER BY of the SELECT clause and not in the order the rows are physically inserted into the table.