Reputation: 3051
Let's assume the following simple table in SQL Server 2012:
CREATE TABLE Person (
Id INT IDENTITY(1, 1) PRIMARY KEY,
Name NVARCHAR(50)
)
And the following corresponding class in C#:
public class Person
{
public int Id {get; set;}
public string Name {get; set;}
}
Consider now the following CreatePerson
method (pseudo code):
public static Person CreatePerson(string name) {
...
DB.Execute("INSERT INTO Person(Name) VALUES (name)", name);
int lastId = DB.Get("SELECT MAX(Id) FROM Person");
return new Person {Id = lastId, Name=name};
}
This method creates a new person row in the db, builds a new Person object and then it returns the created object that is supposed to contain the database generated Id.
Is it safe and/or correct (from a concurrency perspective) to get the last generated Id by using the following SELECT statement?
SELECT MAX(Id) FROM Person
I am concerned about the following scenario:
person 1
person 2
person 1
Note that USER A and USER B here refers to threads handling the two separate queries to the database.
Upvotes: 0
Views: 121
Reputation: 31991
No it is not safe,you can use this procedure for data insert and get your lastId by using scopre_Identity function
create PROCEDURE Your_procedure_for_insert
@Name VARCHAR(50),
@lastID INT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO Person
(
Name
)
VALUES
(
@Name
);
SET @lastID = SCOPE_IDENTITY();
END;
Upvotes: 2
Reputation: 5031
If you wanted to get the last identity value inserted by a person on that particular scope, use Scope_Identity()
.
If you wanted to get the last identity value inserted to a particular table across the scope, you can go with @@identity
.
If you wanted to get the current identity value of a particular table, use Ident_Current ('Yourtablename')
.
Upvotes: 4