Author |
Topic |
tech1
Starting Member
49 Posts |
Posted - 2012-02-07 : 11:31:34
|
What is the best way of obtaining the last generated ID or a new ID for a bigint column?I want to make sure there wont be any "clashes" across all sessions.I know we have Scope_Identity and Ident_Current('tableName') but which is better?I do believe Ident_Current is better but would appreciate your thoughts. I just need the next ID available so I can insert it into related tables.Thanks |
|
russell
Pyro-ma-ni-yak
5072 Posts |
Posted - 2012-02-07 : 12:15:45
|
http://blog.sqlauthority.com/2007/03/25/sql-server-identity-vs-scope_identity-vs-ident_current-retrieve-last-inserted-identity-of-record/ |
 |
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-02-07 : 12:42:28
|
quote: Originally posted by tech1 What is the best way of obtaining the last generated ID or a new ID for a bigint column?I want to make sure there wont be any "clashes" across all sessions.I know we have Scope_Identity and Ident_Current('tableName') but which is better?I do believe Ident_Current is better but would appreciate your thoughts. I just need the next ID available so I can insert it into related tables.Thanks
is it always single row insertion or batch insertion?------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
X002548
Not Just a Number
15586 Posts |
Posted - 2012-02-07 : 13:13:32
|
DECALRE @Rowcount int, @Error int, @Scope_Identity intINSERT Statement...SELECT @Rowcount = @@ROWCOUNT, @Error = @@ERROR, @Scope_Identity = SCOPE_IDENTITY()..do error/logic handlingl...use @Scope_Identity as the key for additional processing against?BOL:http://msdn.microsoft.com/en-us/library/ms190315.aspx[/quote]SCOPE_IDENTITY, IDENT_CURRENT, and @@IDENTITY are similar functions because they return values that are inserted into identity columns.IDENT_CURRENT is not limited by scope and session; it is limited to a specified table. IDENT_CURRENT returns the value generated for a specific table in any session and any scope. For more information, see IDENT_CURRENT (Transact-SQL).SCOPE_IDENTITY and @@IDENTITY return the last identity values that are generated in any table in the current session. However, SCOPE_IDENTITY returns values inserted only within the current scope; @@IDENTITY is not limited to a specific scope.For example, there are two tables, T1 and T2, and an INSERT trigger is defined on T1. When a row is inserted to T1, the trigger fires and inserts a row in T2. This scenario illustrates two scopes: the insert on T1, and the insert on T2 by the trigger.Assuming that both T1 and T2 have identity columns, @@IDENTITY and SCOPE_IDENTITY will return different values at the end of an INSERT statement on T1. @@IDENTITY will return the last identity column value inserted across any scope in the current session. This is the value inserted in T2. SCOPE_IDENTITY() will return the IDENTITY value inserted in T1. This was the last insert that occurred in the same scope. The SCOPE_IDENTITY() function will return the null value if the function is invoked before any INSERT statements into an identity column occur in the scope.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. [/bol]Brett8-)Hint: Want your questions answered fast? Follow the direction in this linkhttp://weblogs.sqlteam.com/brettk/archive/2005/05/25/5276.aspxWant to help yourself?http://msdn.microsoft.com/en-us/library/ms130214.aspxhttp://weblogs.sqlteam.com/brettk/http://brettkaiser.blogspot.com/ |
 |
|
X002548
Not Just a Number
15586 Posts |
|
Kristen
Test
22859 Posts |
Posted - 2012-02-07 : 13:41:17
|
"Best way to get last ID?"What's the underlying problem that you are trying to solve? (or avoid !!) |
 |
|
X002548
Not Just a Number
15586 Posts |
|
GilaMonster
Master Smack Fu Yak Hacker
4507 Posts |
Posted - 2012-02-07 : 14:11:54
|
quote: Originally posted by tech1 I do believe Ident_Current is better but would appreciate your thoughts.
So if two users insert at the same time, you want both of them to get the same value back, the higher of the identity values that the two of them inserted?Have you considered using the OUTPUT clause?--Gail ShawSQL Server MVP |
 |
|
tech1
Starting Member
49 Posts |
Posted - 2012-02-08 : 03:10:19
|
What does the output parameter have to do with anything in this case? :-)I am certainly using that to return the userID back to the client/.NET but I want the DB to be the one to get the last possible ID available for the user.so if Ident_current is "poor" (from what I was reading on MSDN, it seemed the right choice because it takes into consideration all sessions and ALL scopes, rather than just the current session and current scope), then what am I left with? SCOPE_IDENTITY? |
 |
|
GilaMonster
Master Smack Fu Yak Hacker
4507 Posts |
Posted - 2012-02-08 : 06:45:01
|
quote: Originally posted by tech1 What does the output parameter have to do with anything in this case? :-)
If that was directed at me, I said nothing about output parameter. I asked if you'd considered the output clause in an insert statementquote: so if Ident_current is "poor" (from what I was reading on MSDN, it seemed the right choice because it takes into consideration all sessions and ALL scopes, rather than just the current session and current scope), then what am I left with? SCOPE_IDENTITY?
@@identity if you have no triggers on the tables, Scope identity or the output clause.Ident_current does not tell you what identity value you inserted was, it tells you just what the identity value is for the table across all sessions by all users. That's a major risk for race conditions. Try this:-- setup code, run firstuse tempDB;gocreate table TestingIdentity (ID int identity,UserName varchar(10))CREATE TABLE [dbo].[Results]( [IdThatThisSessionInserted] [int] NULL, [IdentCurrent] [numeric](38, 0) NULL, [SessionName] [varchar](10) NULL)go In query window 1:SET NOCOUNT ONgoWAITFOR TIME '13:37' -- set to a couple minutes time so that all 3 start together.goINSERT INTO TestingIdentity (UserName) VALUES ('Session 1')-- This will get the latest row that this session insertedINSERT INTO dbo.Results ( IdThatThisSessionInserted , IdentCurrent , SessionName )SELECT TOP 1 ID AS IdThatThisSessionInserted, IDENT_CURRENT('TestingIdentity') AS IdentCurrent, UserName AS SessionNameFROM TestingIdentity WHERE UserName = 'Session 1' ORDER BY ID DESC GO 200 in query window 2:SET NOCOUNT ONgoWAITFOR TIME '13:37'-- set to the same time as window 1goINSERT INTO TestingIdentity (UserName) VALUES ('Session 2')-- This will get the latest row that this session insertedINSERT INTO dbo.Results ( IdThatThisSessionInserted , IdentCurrent , SessionName )SELECT TOP 1 ID AS IdThatThisSessionInserted, IDENT_CURRENT('TestingIdentity') AS IdentCurrent, UserName AS SessionNameFROM TestingIdentity WHERE UserName = 'Session 2' ORDER BY ID DESC GO 200 in query window 3SET NOCOUNT ONgoWAITFOR TIME '13:37' -- set to same time as window 1goINSERT INTO TestingIdentity (UserName) VALUES ('Session 3')-- This will get the latest row that this session insertedINSERT INTO dbo.Results ( IdThatThisSessionInserted , IdentCurrent , SessionName )SELECT TOP 1 ID AS IdThatThisSessionInserted, IDENT_CURRENT('TestingIdentity') AS IdentCurrent, UserName AS SessionNameFROM TestingIdentity WHERE UserName = 'Session 3' ORDER BY ID DESC GO 200 Run all three simultaneously and wait until they're finished. Once they're all done...SELECT * FROM dbo.Results AS r WHERE IdThatThisSessionInserted != IdentCurrent I got 158 results in my first test. Pretty impressive since only 600 rows were inserted in total. In other words, in 25% of the cases, ident_current returned an identity value that a completely different session had inserted, one that was no relation at all to the row that had just been inserted by that session.--Gail ShawSQL Server MVP |
 |
|
DonAtWork
Master Smack Fu Yak Hacker
2167 Posts |
Posted - 2012-02-08 : 07:03:53
|
Kristen asked once: What is the problem you are trying to solve? You seem to be asking "Should i use a crowbar, a hammer, or a brick?" and we have NO idea what you are trying to do.http://weblogs.sqlteam.com/jeffs/archive/2008/05/13/question-needed-not-answer.aspxHow to ask: http://weblogs.sqlteam.com/brettk/archive/2005/05/25/5276.aspxFor ultra basic questions, follow these links.http://www.sql-tutorial.net/ http://www.firstsql.com/tutor.htm http://www.w3schools.com/sql/default.asp |
 |
|
tech1
Starting Member
49 Posts |
Posted - 2012-02-08 : 07:47:04
|
Thanks all.Don: the problem is that I need the userID returned back to .NET via the output param. Thats ok but I need to know what the userID will be when the record has been inserted into the User table, as then I need to insert data into the next related table in the same SPROC and using that userID as the referencing ID |
 |
|
Kristen
Test
22859 Posts |
Posted - 2012-02-08 : 08:14:51
|
Then you need the UserID from the record you have JUST inserted. Either use OUTPUT or scope_identity() [if you have a oolumn in the table that has the IDENTITY property) |
 |
|
tech1
Starting Member
49 Posts |
Posted - 2012-02-08 : 08:19:49
|
yes thats exactly what the question is :-)should I use Scope_Identity, @@Identity, Ident_current?I always use Scope_Identity but just want to make sure im not missing something. |
 |
|
GilaMonster
Master Smack Fu Yak Hacker
4507 Posts |
Posted - 2012-02-08 : 09:36:34
|
Go have a look at my nice long example of why ident_current is a poor idea (unless you like incorrect results part of the time)As for how you do itquote: @@identity if you have no triggers on the tables, Scope identity or the output clause.
--Gail ShawSQL Server MVP |
 |
|
Kristen
Test
22859 Posts |
Posted - 2012-02-08 : 09:41:42
|
quote: Originally posted by tech1 yes thats exactly what the question is :-)should I use Scope_Identity, @@Identity, Ident_current?
I just answered that, or do you need some clarification of the answer I gave you? |
 |
|
tech1
Starting Member
49 Posts |
Posted - 2012-02-08 : 10:02:00
|
Hmm. thanks Kristen |
 |
|
X002548
Not Just a Number
15586 Posts |
|
russell
Pyro-ma-ni-yak
5072 Posts |
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-02-08 : 14:10:42
|
quote: Originally posted by tech1 Hmm. thanks Kristen
best way is to use output clause to capture id generated by getting it from inserted table. This even works for batch insertions and you can capture ids generated in a temporary table if you want------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
|