312

If I have an insert statement such as:

INSERT INTO MyTable ( Name, Address, PhoneNo ) VALUES ( 'Yatrix', '1234 Address Stuff', '1112223333' ) 

How do I set @var INT to the new row's identity value (called Id) using the OUTPUT clause? I've seen samples of putting INSERTED.Name into table variables, for example, but I can't get it into a non-table variable.

I've tried OUPUT INSERTED.Id AS @var, SET @var = INSERTED.Id, but neither have worked.

6
  • 3
    I know about @@SCOPE_IDENTITY already, I specifically want to know how to do it with OUPUT. Thanks. Commented Jun 12, 2012 at 15:04
  • 6
    You need to insert it into a table variable then select from that. There is no syntax to assign directly to a scalar variable from the OUTPUT clause. Commented Jun 12, 2012 at 15:07
  • 4
    The OUTPUT clause has to output into a table or table variable.. Commented Jun 12, 2012 at 15:07
  • 8
    The OUTPUT clause writes to a table. It can be a table variable, temporary table, ... . Commented Jun 12, 2012 at 15:07
  • 3
    My question specifically asks for the OUTPUT clause. Commented Sep 30, 2016 at 18:33

2 Answers 2

624

You can either have the newly inserted ID being output to the SSMS console like this:

INSERT INTO MyTable(Name, Address, PhoneNo) OUTPUT INSERTED.ID VALUES ('Yatrix', '1234 Address Stuff', '1112223333') 

You can use this also from e.g. C#, when you need to get the ID back to your calling app - just execute the SQL query with .ExecuteScalar() (instead of .ExecuteNonQuery()) to read the resulting ID back.

Or if you need to capture the newly inserted ID inside T-SQL (e.g. for later further processing), you need to create a table variable:

DECLARE @OutputTbl TABLE (ID INT) INSERT INTO MyTable(Name, Address, PhoneNo) OUTPUT INSERTED.ID INTO @OutputTbl(ID) VALUES ('Yatrix', '1234 Address Stuff', '1112223333') 

This way, you can put multiple values into @OutputTbl and do further processing on those. You could also use a "regular" temporary table (#temp) or even a "real" persistent table as your "output target" here.

Sign up to request clarification or add additional context in comments.

13 Comments

The answer here for the code behind was concise. ExecuteScalar() FTW
You can insert the result in a real persistent table - this is extremely fantastic because it means that you can INSERT information in TWO tables at the same time.
Don't ever use @@IDENTITY to pull from the top. Foud out the hard way working with triggers and since they were recording history of changes made to one table and inserting into a new table at the same time @@IDENTITY started returning back values from the history table. hilarity ensues from there! Please use marc_s' solution. for the time being I have went with the @OutputTbl method, but I'm intrigued by the other options.
OUTPUT INTO is extremely fantastic except that "The target table of the OUTPUT INTO clause cannot be on either side of a (primary key, foreign key) relationship", which for me is about 99% of potential use cases. I assume this is because the OUTPUT clause can return data even when the transaction is rolled back, but it's a little annoying it is so hard to insert into data into related tables A and B in one shot.
@EricBishard SCOPE_IDENTITY() works better for that.
|
-2

I didn't like the 'trust me, it's the last ID somewhere' element of the above, so browsed Learn.Microsoft and with a bit of jiggling got a neat and exact solution, informed by Micrsosoft examples. (You might not like the old-man-style code, but hey, whatever). It's a C# function but you can extract the SQL elements as required.

const string queryString = "DECLARE @MyTableVar TABLE(NewParaID INT); " + "INSERT into dbo.Para(ParaText) " + "OUTPUT INSERTED.ParaID INTO @MyTableVar " + "VALUES(@para); " + "SELECT NewParaID FROM @MyTableVar; "; using (SqlConnection connection = new(m_sConnectionString)) { SqlCommand command = new(queryString, connection); command.Parameters.AddWithValue("@para", sPara); try { connection.Open(); nParaID = (int)command.ExecuteScalar(); } catch (Exception ex) { sError = ex.Message; bResult = false; } } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.