Get the IDENTITY Values that were Generated by an INSERT Statement in SQL Server

The good thing about having IDENTITY columns in SQL Server is that they automatically generate a unique value for every row that’s inserted into a table. This saves us from having to insert our own unique values, and I’m not going to complain about that.

But obvious question you might ask; What if I need to know the value that was generated for each column I just inserted?

Fortunately, the solution may be easier than you think!

The OUTPUT Clause

SQL Server provides us with the OUTPUT clause that we can use to return data affected during INSERT, UPDATE, DELETE, or MERGE operations. We can use this handy clause to return the IDENTITY values that were generated when we did an INSERT operation.

Here’s an example:

-- Create a sample table
CREATE TABLE Products (
    ProductID INT IDENTITY, 
    Name NVARCHAR(50), 
    Price DECIMAL(10,2)
    );

-- Insert data and capture the output
INSERT INTO Products (Name, Price)
OUTPUT 
    INSERTED.ProductID, 
    INSERTED.Name,
    INSERTED.Price
VALUES 
    ('Product A', 9.99), 
    ('Product B', 19.99);

Output:

ProductID  Name       Price
--------- --------- -----
1 Product A 9.99
2 Product B 19.99

Here, we inserted two rows into the table, and we used the OUTPUT clause to return the values of all columns – including the IDENTITY column.

In this case the ProductID column is the IDENTITY column, and its values were automatically generated by SQL Server when the rows were inserted. The OUTPUT clause was able to capture those values and return them for us to peruse.

In this simplistic example, I could have easily predicted the result, given I’d only just created the table and the default value for IDENTITY columns is 1, incrementing by 1. But this technique could come in handy when dealing with tables that already contain lots of data, and perhaps have lots of inserts and/or deletes happening. In such cases, we’d have no idea what the value of the IDENTITY column would be when inserting our next row. The OUTPUT clause can be particularly beneficial here, as it eliminates the need to do a separate SELECT statement just to find out the value that was inserted into the column (which could adversely impact on performance).

Saving the Result

We can save the result of the OUTPUT clause to a table or table variable so that we can process it further if needed:

-- Create a table variable to store output
DECLARE @InsertedProducts TABLE (
    ProductID INT, 
    Name NVARCHAR(50), 
    Price DECIMAL(10,2)
    );

-- Insert data and capture the output
INSERT INTO Products (Name, Price)
OUTPUT INSERTED.ProductID, INSERTED.Name, INSERTED.Price INTO @InsertedProducts
VALUES ('Product C', 24.50), ('Product D', 7.00);

-- Display the captured output
SELECT * FROM @InsertedProducts;

Output:

ProductID  Name       Price
--------- --------- -----
3 Product C 24.5
4 Product D 7

Here, we captured the newly inserted values into the @InsertedProducts table variable. In this case, we just selected the contents, but we could do anything else we might want to do with this data.