views:

43

answers:

5

Hello,

I'd like to get the value of the id column for an object just after I've created it. But I don't want to run another query for that. My book for beginner (SQL Server 2008 for Dummies) says that there are 2 tables (inserted and deleted) that hold the last row(s) that have been inserted, updated, or deleted.

Unfortunately, only Triggers (says the book) can access those tables. But, if I use triggers, they will go off each time I "insert" a row even when I don't need them that functionality.

Can I obtain the same effect with a Store Procedure (without having to run a separate query?)

This is what I'm trying to do

CREATE PROCEDURE myProcedure
DECLARE @OrganizationName
        @ColumnID OUTPUT
AS
INSERT INTO Organization (OrganizationName)
VALUES (@OrganizationName)

SET @ColumnID = (// Please, I need Help here ...)

Thanks for helping

A: 
SELECT @@IDENTITY;
x2
+5  A: 

You can use SCOPE_IDENTITY():

SELECT @ColumnID = SCOPE_IDENTITY()
RedFilter
+1 for SCOPE_IDENTITY() over @@IDENTITY
AdaTheDev
@OrbMan - Good to have u again. Can u edit my above sample?
Richard77
@Richard77: see above
RedFilter
@OrbMan - hope you don't mind, I corrected the variable assignment
AdaTheDev
@Ada: thanks, no coffee yet!
RedFilter
@AdaTheDev: Why do you suggest to use SELECT instead of SET even when you don't select the data from somewhere? I would suggest the opposite, because it's a plain assignment.
Guffa
@Guffa, it is faster to assign multiple variables using `SELECT @x=...,@y=...,@z=...` then issuing `SET @x=..;SET @y=...;@z=...;` I tend to use SELECT if I need to assign multiple in one section, but SET if I only have one. It is easy enough to just use SELECT everywhere.
KM
@Guffa - It was just instinctive, no reason for me giving SELECT instead of SET as obviously SET would be fine too - there's no performance implication. I do usually use SET when just assigning a single value like this, but @KM was spot on - often I want to assign more than one value so use SELECT.
AdaTheDev
@thanks to all -- I guess it's better to start an other thread to get the answer for my other question, which is to retrieve the value of the above SPROC using Linq
Richard77
+1  A: 

Use SCOPE_IDENTITY() function:

SELECT @ColumnID = SCOPE_IDENTITY()

Cheers Matthias

Mudu
A: 

Just to clear up a misconception about triggers. You can create triggers "FOR UPDATE" which will cause them to fire only when an update occurs, and not for an insert.

But everyone else here is right, use SCOPE_IDENTITY().

The reason you would use SCOPE_IDENTITY() over @@IDENTITY is that @@IDENTITY is global to the server, so if you have triggers that create a record in another table with an IDENTITY field, the @@IDENTITY will hold that value.

SCOPE_IDENTITY() ensures that you get the ID from the table you just inserted to.

Jeremy
A: 

you can use the OUTPUT clause, which has access to INSERTED and DELETED (DELETED only on on update/delete):

DECLARE @NewRows table (YourIdentityColumn ....
                       ,any other columns here
                       )

INSERT INTO Organization
        (OrganizationName)
        OUTPUT INSERTED.YourIdentityColumn, any other columns here
            INTO @NewRows
    VALUES (@OrganizationName)

of course this is best when inserting multiple rows at a time:

INSERT INTO Organization
        (OrganizationName)
        OUTPUT INSERTED.YourIdentityColumn, any other columns here
            INTO @NewRows
    SELECT
        col1, col2, col3...
        FROM ...

you could also just return a result set (it will insert the row and return a result set to the procedure caller), from your INSERT:

INSERT INTO Organization
        (OrganizationName)
        OUTPUT INSERTED.YourIdentityColumn, any other columns here
    VALUES (@OrganizationName)
KM
and don't forget you can have multiple OUTPUT clauses on a single statement, so you can send the output to a log table, local variable and a result set all from within the one single original command.
KM

related questions