How can I get back the autogenerated ID for a new record I just inserted? (Using ASP classic and MSSQL 2005)
SELECT @@Identity or SELECT SCOPE_IDENTITY() both work however Selecting SCOPE_Identity() is safer because it returns the last auto generated ID within your current scope. So for example assume we have a table called ScopeIDTable and on this table we have a trigger. This trigger will insert into a record into TriggerIdTable both tables have an auto increment column.
If you use SELECT @@Identity you will get the last auto increment in that session which would be the Id generated from within the trigger (TriggerIdTable).
If you use SELECT SCOPE_IDENTITY() you will get the id from your ScopeIdTable.
I always wondered why one would ever want to use
@@identity
since
select scope_identity()
obviously is the most save way to accomplish what Scot is asking for.
You run the query
select scope_identity()
using the same database connection, before doing anything else with it. The result is, as you probably expect, a record set containing a single row that has a single field. You can access the field using index 0, or you can give it a name if you prefer that:
select scope_identity() as lastId
Thanks all who suggested SELECT SCOPE_IDENTITY(). I was able to create a stored procedure:
USE [dbname]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[spInsert]
(
@Nn varchar(30)
)
AS
BEGIN TRANSACTION InsertRecord
INSERT INTO A (Nn)
VALUES (@Nn)
SELECT NewID = SCOPE_IDENTITY() -- returns the new record ID of this transaction
COMMIT TRANSACTION InsertRecord
and call the sproc using VB:
Dim strNn '<- var to be passed'
Set cn = Server.CreateObject("ADODB.Connection")
connectString = "DSN"
cn.Open connectString, "user", "PW0rd"
Set rs = Server.CreateObject("ADODB.Recordset")
set rs = cn.Execute("EXEC [dbname].[dbo].[A] @Nn=" & strNn)
'return the value'
resultID = rs(0)
I can now use resultID anytime I refer to the newly created ID.
SELECT @@IDENTITY usually works, but could return the identity of a record inserted because of a trigger or something, and not the original.
SELECT SCOPE_IDENTITY is what I'd recommend. It returns values inserted only within the current scope.
There is also a "IDENT_CURRENT(tablename)" that returns the last identity inserted for a specific table.
There are three ways to get the the last identity in sql.
They were already mentioned by others, but for completeness:
Additionally, there are three ways to take that ID and return it to your client code:
Use an output parameter in a stored procedure
INSERT INTO [MyTable] ([col1],[col2],[col3]) VALUES (1,2,3);
SELECT @OutputParameterName = Scope_Identity();
Use a return value.
INSERT INTO [MyTable] ([col1],[col2],[col3]) VALUES (1,2,3);
Return Scope_Identity();
Select the id into a result set. For example, your sql statement would look something like this:
Dim ResultID As Integer
Dim strSQL As String
strSQL = "INSERT INTO [MyTable] ([col1],[col2],[col3]) VALUES (1,2,3); SELECT Scope_Identity();"
rsResults.Open strSQL, oConn
ResultID = rsResults("ID")
Unfortunately (or fortunately, from my point of view) my Classic ASP it too far gone to show examples of the first two from client code.