How do I increment a DB id

  • Help! I was wondering how I increment a database id as I insert values into a table in SQL Server? I need to grab the last inserted value and then increment that by 1. I am not sure if it has the IDENTITY property put on it in the table and if it does not I do not have access to add it. Can any one help?

    Thanks

  • Assuming I understood the question, if you're asking how to determine what the last identity value inserted was is to use the SCOPE_IDENTITY() function. This returns the last Identity value generated by the script, procedure or trigger it's called from.

    If you're asking what to do when you don't have an identity field, you can use the MAX statement to get the highest value and then add one to it.

    "The credit belongs to the man who is actually in the arena, whose face is marred by dust and sweat and blood"
    - Theodore Roosevelt

    Author of:
    SQL Server Execution Plans
    SQL Server Query Performance Tuning

  • Thanks for the quick reply. I am pretty new at the SQL Server stuff... if I am insert values in what would be syntax be on those two statements (IDENTITY and MAX?)? Thanks so much...

  • You'd use the SCOPE_IDENTITY like this:

    INSERT INTO table

    (Desc,UpdateDate,Whatever)

    VALUES

    ('My Description','1/14/2007','Something)

    SELECT SCOPE_IDENTITY()

    That would insert a row into the table and then give you the identity value generated by that table from the insert. If you didn't have an identity value, but you had an integer column that you generated a value to add to it, quick & dirty, here's how you could do that

    DECLARE @MyId int

    SELECT @MyId = MAX(Id)

    FROM table

    INSERT INTO table

    (Id,Desc)

    VALUES

    (@MyId+1,'My Description')

    I say that's quick and dirty because, when using that kind of approach, you need to worry about locking and concurrency. So there are more sophisticated ways of doing it than what I showed.

    Also, you might want to know about something called IDENTITY_INSERT. It's a way of adding your own value to an identity column. There are tons of caveats around it's use, so I'd suggest reading up on it in the Books Online (BOL) before you use it.

    "The credit belongs to the man who is actually in the arena, whose face is marred by dust and sweat and blood"
    - Theodore Roosevelt

    Author of:
    SQL Server Execution Plans
    SQL Server Query Performance Tuning

  • I will read up on that, and thanks so much... I just was not for sure what to even search or look for...

    Thanks Again for your help.

  • on the other hand,

    if you use identity in your column definition, sqlserver will generate the next number for you.

    And with sql2005 you could just add

    OUTPUT [yourIDcolumn]

    to your statement and you'd have the value returned with the returnvalue of the insert statement and you can skip the scope_identity select.

    CREATE TABLE #tbl_whatever (colid int identity (1,1), username varchar(50) DEFAULT suser_sname(),

    uniqueid uniqueidentifier DEFAULT NEWID(),

    Creationdate datetime default getdate(),

    rANDOMVALUE int default rand()*5000000)

    insert into #tbl_whatever (username)

    OUTPUT inserted.* values (DEFAULT)

    declare @outputtable table (newvalue int, oldvalue int)

    update #tbl_whatever

    set randomvalue = randomvalue + 1

    OUTPUT inserted.randomvalue, deleted.randomvalue into @outputtable

    select * from @outputtable

    Johan

    Learn to play, play to learn !

    Dont drive faster than your guardian angel can fly ...
    but keeping both feet on the ground wont get you anywhere :w00t:

    - How to post Performance Problems
    - How to post data/code to get the best help[/url]

    - How to prevent a sore throat after hours of presenting ppt

    press F1 for solution, press shift+F1 for urgent solution 😀

    Need a bit of Powershell? How about this

    Who am I ? Sometimes this is me but most of the time this is me

  • Since you're in 2005 - you can avoid all of the scope_identity nonsense by using the OUTPUT predicate from within the INSERT statement.

    It looks something like

    declare @nextid as integer

    declare @tbl table (id int)

    INSERT into dbo.mytable (lname)

    OUTPUT inserted.id into @tbl

    values('bob')

    select @nextid=id from @tbl

    select @nextid --now do something with it

    The bigger question is - why do you need it? All of these approaches are making assumptions that you're dealing with only one record at a time, which might be a messy assumption in a lot of cases. Also - forcing SQL Server to only operate one record at a time tends to make it behave badly (it likes to play with LOTS of toys at the same time).

    What are you doing with it?

    ----------------------------------------------------------------------------------
    Your lack of planning does not constitute an emergency on my part...unless you're my manager...or a director and above...or a really loud-spoken end-user..All right - what was my emergency again?

  • I knew of the OUTPUT clause, but I'd only really thought of it for stuff like auditing. This is really useful. So, if you had a multi-row insert, you'd just output to a table variable? I'm going to have to experiment a bit with this.

    "The credit belongs to the man who is actually in the arena, whose face is marred by dust and sweat and blood"
    - Theodore Roosevelt

    Author of:
    SQL Server Execution Plans
    SQL Server Query Performance Tuning

  • hey thanks... I am going to have to go with the Max function below, one question I would have is how can I put this in a loop to increment or keep calling the MAX function and insert the lastest value in?

    My SELECT Query pulls back several records I need to change.

    DECLARE @MyId int

    SELECT @MyId = MAX(ORG_KEY) from orgs

    select @MyId+1,id,name,org_id from Proj where project like '11450%'

  • Grant Fritchey (1/14/2008)


    I knew of the OUTPUT clause, but I'd only really thought of it for stuff like auditing. This is really useful. So, if you had a multi-row insert, you'd just output to a table variable? I'm going to have to experiment a bit with this.

    Indeed, everything is available in the inserted-object and can be externalized using the output clause.

    CREATE TABLE #tbl_whatever (colid int identity (1,1), username varchar(50) DEFAULT suser_sname(),

    uniqueid uniqueidentifier DEFAULT NEWID(),

    Creationdate datetime default getdate(),

    rANDOMVALUE int default rand()*5000000)

    insert into #tbl_whatever (username)

    OUTPUT inserted.*

    values (DEFAULT)

    insert into #tbl_whatever (username)

    OUTPUT inserted.*

    select username + '_Run2' from #tbl_whatever

    insert into #tbl_whatever (username)

    OUTPUT inserted.*

    select username + '_Run3' from #tbl_whatever

    insert into #tbl_whatever (username)

    OUTPUT inserted.*

    select username + '_Run4' from #tbl_whatever

    -- what auditors like about OUTPUT

    declare @outputtable table (newvalue int, oldvalue int)

    update #tbl_whatever

    set randomvalue = randomvalue + 1

    OUTPUT inserted.randomvalue, deleted.randomvalue into @outputtable

    select * from @outputtable

    Johan

    Learn to play, play to learn !

    Dont drive faster than your guardian angel can fly ...
    but keeping both feet on the ground wont get you anywhere :w00t:

    - How to post Performance Problems
    - How to post data/code to get the best help[/url]

    - How to prevent a sore throat after hours of presenting ppt

    press F1 for solution, press shift+F1 for urgent solution 😀

    Need a bit of Powershell? How about this

    Who am I ? Sometimes this is me but most of the time this is me

  • Here we have a double edged sword. On the one side, I've got a more effecient tool to use in my queries. On the other side, you just handed me a bunch of work because I know I've got some queries I can rewrite to benefit from this.

    So 😛

    Thanks.

    "The credit belongs to the man who is actually in the arena, whose face is marred by dust and sweat and blood"
    - Theodore Roosevelt

    Author of:
    SQL Server Execution Plans
    SQL Server Query Performance Tuning

  • as long as you don't send me the bills, I'm happy with that. :hehe:

    Indeed SQL2005 has some nice new stuff...

    Johan

    Learn to play, play to learn !

    Dont drive faster than your guardian angel can fly ...
    but keeping both feet on the ground wont get you anywhere :w00t:

    - How to post Performance Problems
    - How to post data/code to get the best help[/url]

    - How to prevent a sore throat after hours of presenting ppt

    press F1 for solution, press shift+F1 for urgent solution 😀

    Need a bit of Powershell? How about this

    Who am I ? Sometimes this is me but most of the time this is me

  • Grant Fritchey (1/14/2008)


    I knew of the OUTPUT clause, but I'd only really thought of it for stuff like auditing. This is really useful. So, if you had a multi-row insert, you'd just output to a table variable? I'm going to have to experiment a bit with this.

    Or - just like you might do with a trigger - you can put it into an existing table. So you could do something like

    Delete from MyTable

    Output deleted.*,getdate() into MyHistoryTable

    ----------------------------------------------------------------------------------
    Your lack of planning does not constitute an emergency on my part...unless you're my manager...or a director and above...or a really loud-spoken end-user..All right - what was my emergency again?

  • Yes, that's exactly the type of auditing function that I had understood the OUTPUT function to be useful for. I just hadn't made the leap to using it with more mundane functions. I'm busy figuring out the rewrites I need on one of my projects right now.

    "The credit belongs to the man who is actually in the arena, whose face is marred by dust and sweat and blood"
    - Theodore Roosevelt

    Author of:
    SQL Server Execution Plans
    SQL Server Query Performance Tuning

  • kipp (1/14/2008)


    hey thanks... I am going to have to go with the Max function below, one question I would have is how can I put this in a loop to increment or keep calling the MAX function and insert the lastest value in?

    My SELECT Query pulls back several records I need to change.

    DECLARE @MyId int

    SELECT @MyId = MAX(ORG_KEY) from orgs

    select @MyId+1,id,name,org_id from Proj where project like '11450%'

    that technique can cause duplicates and performance problems if you create lots of orgs. a unique index on orgs.ORG_KEY would help and ensure no duplicates are created for orgs.ORG_KEY, but won't protect you from collisions (two sessions trying to add the same ORG_KEY).

    here's a table and stored procedure for sequencing:

    create table Sequencing (

    objectName varchar(128) not null,

    sequence int null default -1,

    constraint PK_SEQUENCING primary key( objectName )

    )

    create procedure dbo.getNextSequence_sp

    @object varchar(256),

    @reserve int = 1,

    @sequence int OUTPUT

    as

    begin

    begin transaction

    update Sequencing

    set sequence = sequence + @reserve

    where objectName = lower(@object)

    if (@@rowcount < 1)

    insert into Sequencing (objectName, sequence ) values (lower(@object), @reserve)

    set @sequence = (select sequence - @reserve

    from Sequencing where objectName = lower(@object))

    commit transaction

    end

    ...

    DECLARE @MyId int

    --SELECT @MyId = MAX(ORG_KEY) from orgs

    exec getNextSequence_sp "orgs.ORG_KEY", 1, @MyId out

    with this technique, you're 'reserving' the sequence value and need not use it immediately (which is often the case with an interactive application). if you know you're going to be added 20 things, all 20 values can be reserved at once.

    the downside of course is the table/proc must be used when creating new values for the reserved object.

Viewing 15 posts - 1 through 15 (of 26 total)

You must be logged in to reply to this topic. Login to reply