tags:

views:

143

answers:

7

I have a table in a SQL Server database that has an auto-generated integer primary key. Without inserting a record into the table, I need to query the database and get what the next auto-generated ID number will be.

I think it's SQL Server version 2005, if that makes a difference.

Is there a way to do this?

+5  A: 

Yes, but it's unreliable because another session might use the expected number.

If you still want to do this, use IDENT_CURRENT

Edit, as the comments have pointed out (improving my answer):

  • you need to add one IDENT_INCR('MyTable') to this to get the potential next number
  • another process may rollback and this number may not be the one used anyway
gbn
yes, and another session may even try to insert something, and then be rolled back but still the next number will go into the tube...
Bogdan_Ch
Technically, that is the last identity used and not the next.
Andrew
Assuming the Increment value is one, but I've not seen it regularly as other than that.
CodeByMoonlight
@CodeByMoonlight: I've always seen it as one also. A safe assumption I'd say... :-)
gbn
Use Ident_incr('tablename') and you eliminate the assumption. Or use the DMV values of the same, I wrote an answer thats somewhere below :)
Andrew
@Andrew: that's what you get for never using IDENT_CURRENT etc...
gbn
@gbn : Absolutely, terrible for code, but when investigating the state of a table trying to reverse a sequence of events, it comes in handy
Andrew
+5  A: 

No, there is not. The ID will only ever be defined and handed out when the actual INSERT happens.

You can check the last given ID by using

DBCC CHECKIDENT('YourTableName')

but that's just the last one used - no guarantee that the next one is really going to be this value + 1 - it could be - but no guarantees

marc_s
technically, there is but you'd never try it...
gbn
You can use ident_incr to get the increment instead of guessing at ident +1 , but as we all agree, not a production code mechanism.
Andrew
A: 

This is pretty much a bad idea straight off the bat, but if you don't anticipate high volume and/or concurrency issues, you could just do something like this

select @nextnum = max(Id) + 1 from MyTable
Joel Martinez
A: 

I don't think thats possible out of the box in MS SQL (any version). You can do this with column type uniqueidentifier and using function NEWID(). For int column, you would have to implement your own sequential generator.

Tomas
this is not the answer to the question :) if you call newid() it will never give you NEXT ID that will be inserted next time (because next time it will be absolutely another GUID value...)
Bogdan_Ch
yeah, but instead of letting sql server define what the next ID will be, he can take that into his own responsibility, generate the newid(), and then use that value in the insert (and for whatever other reason it is that he needs to know it)
Joel Martinez
+2  A: 

The only way to get a number that is guranteed not to be used by another process (i.e., a race condition) is to do the insert - is there any reason you can't do a NULL insert (i.e., just insert into the table with NULLs or default values for all other columns) and then subsequently UPDATE it?

i.e.,

CREATE TABLE bob (
  seq INTEGER IDENTITY (1,1) NOT NULL,
  col1 INTEGER NULL
)
GO
DECLARE @seqid INTEGER

INSERT INTO bob DEFAULT VALUES
SET @seqid = SCOPE_IDENTITY()
-- do stuff with @seqid
UPDATE bob SET col1 = 42 WHERE seq = @seqid
GO
Chris J
+1  A: 

You shouldn't use the technique in code, but if you need to do it for investigative purposes:

select ident_current(‘foo’) + ident_incr(‘foo’)

That gives you the last value generated + the incrementation for the identity, so should represent the next choice SQL would make without inserting a row to find out. This is a correct value even if a rollback has pushed the value forwards - but again, this is investigative SQL not stuff I would put in code.

The two values can also be found in the sys.identity_values DMV, the fields are increment_value and last_value.

Andrew
A: 

Another way, depending on what your doing, is inserting whatever data goes into the table, and then using @@identity to retrieve the id of the record inserted.

example:

declare @table table (id int identity(1,1), name nvarchar(10))

insert into @table values ('a')
insert into @table values ('b')
insert into @table values ('c')
insert into @table values ('d')

select @@identity

insert into @table values ('e')
insert into @table values ('f')

select @@identity
DForck42