SQL Server: How to get the Last Inserted Identity value. What is the fastest way?
Hello friends,
Very often after inserting a row in a table it is necessary to know what is the id of the row just inserted.
We have various methods but what is the fastest?
Today we take a watch to this question!
Enjoy the reading!
As usually for maximum clarity we will proceed with an example using our standard table.
It has an identity column called ID
The classic way!
SELECT MAX(ID) FROM ORDTES
(1 riga interessata)
Tabella 'OrdTes'. Conteggio analisi 1, letture logiche 2, letture fisiche 0, letture read-ahead 0, letture logiche LOB 0, letture fisiche LOB 0, letture read-ahead LOB 0.
(1 riga interessata)
SELECT TOP 1 ID FROM ORDTES ORDER BY ID DESC
(1 riga interessata)
Tabella 'OrdTes'. Conteggio analisi 1, letture logiche 2, letture fisiche 0, letture read-ahead 0, letture logiche LOB 0, letture fisiche LOB 0, letture read-ahead LOB 0.
We can note that with these first two methods we access the table albeit through the index that contains the ID column. It is fast because since the index is sorted by ID it is sufficient to read the first line.
There also other ways which we will now analyze.
First you should know what is a scope.
What is The Scope
A scope is simply a module that contain T-SQL code. A stored procedure, a trigger, a function, or batch in module.
Therefore, if two T-SQL statements are in the same stored procedure, function, or batch, they are in the same scope
There are three similar functions but each one has its own particularity.
The diagram below should summarize well..
Talking about @@IDENTITY, SCOPE_IDENTITY() and IDENT_CURRENT(‘tablename’)
@@IDENTITY
The @@identity function returns the last identity value with this characteristics.
- For the current active connection (session),
- regardless of the table that produced the value,
-
regardless of the scope of the statement that produced the value.
SCOPE_IDENTITY()
It returns the last IDENTITY value:
- For the current active connection (session),
- regardless of the table that produced the value.
-
and by a statement in the
same scope,
so SCOPE_IDENTITY(), unlike @@IDENTITY, will return the last identity value created in the current session, but it will also limit it to your current scope as well.
In other words, it will return the last identity value that you explicitly created, rather than any identity that was created by a trigger or a user defined function.
The Any scope problem
So there is a problem due to of the “regardless of the scope”: If you have a trigger on a table that causes an identity to be created in another table because you will get the identity that was created last, even if it was the trigger that created it.
Infact assuming that both T1 and T2 have identity columns, @@IDENTITY and SCOPE_IDENTITY return different values at the end of an INSERT statement on T1.
While @@IDENTITY returns the last identity column value inserted across any scope in the current session. This is the value inserted in T2. SCOPE_IDENTITY() returns the IDENTITY value inserted in T1. This was the last insert that occurred in the same scope.
The SCOPE_IDENTITY() function returns the null value if the function is invoked before any INSERT statements into an identity column occur in the scope.
Finally we have the
IDENT_CURRENT(‘tablename’)
It returns the last IDENTITY value
- produced in a table,
- regardless of the connection that created the value, and
-
regardless of the scope of the statement
that produced the value.
IDENT_CURRENT is not limited by scope and session; it is limited to a specified table. IDENT_CURRENT returns the identity value generated for a specific table in any session and any scope.
Note that: Failed statements and transactions can change the current identity for a table and create gaps in the identity column values. The identity value is never rolled back even though the transaction that tried to insert the value into the table is not committed. For example, if an INSERT statement fails because of an IGNORE_DUP_KEY violation, the current identity value for the table is still incremented.
Finally speaking of performances.
@@IDENTITY, SCOPE_IDENTITY and IDENT_CURRENT are 5 times fastest that quering that table directly!
Thank you so much for providing information about most useful and popular aspects of SQL and its functions such as Insert,Update and Delete.
ReplyDeleteSQL Server Load Rest API