Quantcast
Channel: Brent Ozar Unlimited®
Viewing all articles
Browse latest Browse all 3153

How to Insert Rows and Get Their Identity Values with the OUTPUT Clause

$
0
0

Say you’ve got a two-step process where you’re:

  1. Inserting rows into a table that has an identity column, then
  2. Querying that table to figure out what identities you got

There’s a a faster way that doesn’t require hitting the table twice: the OUTPUT clause.

I’ll demonstrate it with the Badges table from the Stack Overflow database, which has an Id column that’s an identity. I’m going to find all of the Users who live in Iceland, give them a badge, and then return the list of badge IDs I just granted:

INSERT INTO dbo.Badges(Name, UserId, Date)
	SELECT N'Sunny Disposition', Id, GETDATE()
	FROM dbo.Users
	WHERE Location = N'Iceland';

SELECT b.Id
	FROM dbo.Badges b
	INNER JOIN dbo.Users u ON b.UserId = u.Id
	WHERE u.Location = N'Iceland'
	  AND b.Name = N'Sunny Disposition'
	  AND b.Date >= DATEADD(SS, -1, GETDATE());

This code pattern is kinda painful because:

  • We lock rows twice (when we read & insert, and then again when we read back what we just did)
  • We have to be careful to only fetch the rows we really just inserted – so we end up putting in all kinds of convoluted logic to work around concurrency problems

Instead, use the OUTPUT clause.

Here’s how to do it without touching the Badges & Users tables twice:

CREATE TABLE #RowsInserted 
	(Id INT, Name NVARCHAR(40), UserId INT, [Date] DATETIME);

INSERT INTO dbo.Badges(Name, UserId, Date)
	OUTPUT INSERTED.Id, INSERTED.Name, INSERTED.UserId, INSERTED.[Date]
		INTO #RowsInserted
	SELECT N'Sunny Disposition', Id, GETDATE()
	FROM dbo.Users
	WHERE Location = N'Iceland';

SELECT * FROM #RowsInserted;

The OUTPUT clause is kinda like the virtual INSERTED/DELETED tables: it lets you grab the output of what you’re doing and redirect it to another place. Presto, less locking, less T-SQL to manage, less guessing as to which rows were affected by your operation.

Isn’t that slick? In my own line of work, I sure don’t need to use it often, but when I do, it’s amazing.

Want to learn more tricks like this?

If you like tricks like this, you’ll love my Mastering Query Tuning class. I’ve got two upcoming sessions: December 11-13 (Fri/Sat/Sun, iCal) and January 12-14 (Tues/Weds/Thurs- iCal.)

If you’ve got a Live Class Season Pass, you can drop in on this class or any of my live online classes at any time. Just head to my current training page, check out the schedule at the bottom of the page, and grab the calendar files for the classes you’re interested in. You don’t have to register ahead of time – just drop in anytime I’m streaming.

If you don’t have one yet, I’m running a Black Friday Sale this month. Time’s running out…

Level 1: Fundamentals
$295
Level 2 for 2 Years
$1,595

My annual Black Friday Sale is on now! Save thousands on the best training classes in the industry.


Viewing all articles
Browse latest Browse all 3153

Trending Articles