SingingEels : Development Community & Resource

Login

Articles

  • ADO.NET (2)
  • ASP.NET (36)
  • Azure (0)
  • LINQ (5)
  • Security (2)
  • Silverlight (3)
  • SQL (7)
  • Standards (5)
  • WCF (2)

Syndication

  • Articles RSS
  • Blogs RSS

Contribute

  • Our Authors List
  • Member Sign-Up
  • Suggestions Box

Get Identity Field and More From Inserts

(May 22 2007 - 05:32:36 AM by Timothy Khouri) - [print article]

Identifying The Problem

Often times when inserting a new record into a table that has an auto-key field (an identity field that is set to auto increment), you may need to get that new ID back to use in other SQL statments. This can be done with @@IDENTITY or SCOPE_IDENTITY(), but those methods are very limited when compared to the new OUTPUT clause in SQL Server 2005. This article will show how and when to use these powerful TSQL features.

The reason why I say that the @@IDENTITY and SCOPE_IDENTITY() options are limited is because 1) they only return numeric fields (so "uniqueidentifier" fields won't work), 2) they can only return the field marked as the table 'identity' (so you can't get a different field that you may be using as the ID), 3) they cannot give back any other auto-generated data such as a timestamp field. Another huge failing is in the case of multiple inserts in one statement. The @@IDENTITY and SCOPE_IDENTITY() options will only return the last record insereted. So if your insert statement added five records, you would only get the ID of the last one.

Intruducing The OUTPUT Clause

SQL Server 2005 intruduces a really amazing new clause that can be used in DELETE, UPDATE and INSERT statements called 'OUTPUT'. The syntax is easy to follow as you basically just append it to the end of your statement and treat it like a SELECT. This small bit of SQL will show how to get the ID column back from an INSERT using SCOPE_IDENTITY() compared to the OUTPUT clause.

-- Here is the sample table we are going to work with.
CREATE TABLE dbo.MicrosoftProducts
(
   ID INT NOT NULL IDENTITY (1, 1),
   ProductName VARCHAR(50) NOT NULL,
   ProductDescription VARCHAR(1000) NOT NULL,
   EntryDate DATETIME DEFAULT GETDATE() NOT NULL
)

-- This will insert a row and retrieve the ID field using @@IDENTITY.

INSERT INTO dbo.MicrosoftProducts (ProductName, ProductDescription)
   VALUES ('SQL Server 2005', 'The best version of SQL ever!')
SELECT @@IDENTITY

-- Now using the OUTPUT clause to get the identity field.

INSERT INTO dbo.MicrosoftProducts (ProductName, ProductDescription)
   OUTPUT INSERTED.ID
       VALUES ('SQL Server 2005', 'The best version of SQL ever!')

At first glance, these three examples above may all seem equal. They all take the same amount of code, and they all return the identity field of the record that was just inserted. However, if we change the desired results slightly we can see the major failings of the first two, and we'll see why the OUTPUT clause is so powerful.

Let's say instead of just wanting to return the new ID to the user, we want to add the EntryDate field to the results that we send back to the user. With the first two options you would have to store the ID in a variable and re-query the table causing much unneeded overhead and code. Whereas with the OUTPUT clause, getting these results are very simple.

Using @@IDENTITY or SCOPE_IDENTITY()

-- This is the same with @@IDENTITY or SCOPE_IDENTITY().
-- We have to hold the new ID in a variable.

DECLARE @NewID INT

INSERT INTO dbo.MicrosoftProducts (ProductName, ProductDescription)
  VALUES ('SQL Server 2005', 'The best version of SQL ever!')

-- Now we have to assign that variable with the new ID.

SELECT @NewID = SCOPE_IDENTITY()

-- Now we have to re-query the table just to get the two fields.

SELECT ID, EntryDate FROM dbo.MicrosoftProducts WHERE ID = @NewID

Using The OUTPUT Clause

-- All we do is add another field to our OUTPUT clause.
INSERT INTO dbo.MicrosoftProducts (ProductName, ProductDescription)
   OUTPUT INSERTED.ID, INSERTED.EntryDate
       VALUES ('SQL Server 2005', 'The best version of SQL ever!')

If that is all the OUTPUT clause could do, it would be worth using. But keep in mind that you can also use it to return multiple results if your insert was more than one record. Another great benefit of the OUTPUT clause is that you can use it for DELETEs and UPDATEs as well. So if you wanted to delete some records based on user input and then show them in a GridView what records have been removed, you could do it in one clean step.

DELETE FROM dbo.MicrosoftProducts OUTPUT DELETED.*

The syntax for UPDATEs is a little different, but even more powerful. There is no "UPDATED" object, but rather you can use "DELETED" or "INSERTED" to represent the list of columns before the change and after the change respectively. Example:

UPDATE dbo.MicrosoftProducts SET ProductName = 'Test'
   OUTPUT DELETED.ProductName AS TheBefore, INSERTED.ProductName AS TheAfter

You must be logged in to add comments. If you have not already done so, you can create an account here. If you already are a member, you first need to login before you can comment.

Developer / Architect / Author

Check Out Dev++

Test your development skills, give proof to recruiters and employers at dev++

Related Blogs

These are the most recent blog posts related to this article.

  • Aspose.Newsletter February 2012 Edition is out Now
  • Remove Item from PST File & Access to Default MS Outlook Folders
  • Embed Videos inside PowerPoint Presentation & Stable PDF Generation
  • Excel to PDF Conversion, XLS, XLSX & ODS Rendering are Improved
  • Convert SVG to Pdf & Render Pdf into Image with Desired Dimensions

Related Ads

SingingEels.com as of Feb 04 2012 - 12:42:58 AM - (0.1250016)