TryCatchFinally.net Some SQL, some .NET, and whatever else

21Feb/110

Lightweight, single-row alternative to OUTPUT clause in T-SQL

SQL Server 2005 adds the option for an OUTPUT clause in your query to act upon table rows and return the old and new values. When I've done queuing in the past, I've used the clause to mark a row as processing and return the value, all in a single operation, so it's lightweight and threadsafe. For example, like this:

UPDATE TOP (1) dbo.MyQueue
   SET ClaimedBy = @Server,
       ClaimTime = @ClaimTime
OUTPUT INSERTED.QueueID,
       INSERTED.SomeData1,
       INSERTED.SomeDate2,
       INSERTED.SomeData3
  INTO #OutputTable (QueueID, Column1, Column2, Column3)
 WHERE Some Criteria...

To do this, you'll need to create a table called #OutputTable that has the right schema, which works well if you're returning multiple rows from your query, but is a little cumbersome to work with if you're only doing one row at a time. If you're only returning a single row from your UPDATE query (as I am here), there's an alternative to OUTPUT that's easier to use - just do variable assignment inline in the UPDATE statement! The query above becomes:

UPDATE TOP (1) dbo.MyQueue
   SET ClaimedBy = @Server,
       ClaimTime = @ClaimTime
       @QueueID = QueueID,
       @OutputVar1 = SomeData1,
       @OutputVar2 = SomeData2,
       @OutputVar3 = SomeData3
 WHERE Some Criteria...

Notice the reversed variable assignment in the second query? I've done away with my table, and my OUTPUT clause, and now I just have the relevant values from the row I'm interested in. Much easier to work with, and as an added bonus (though I hope you're not in this situation), it works just fine in SQL 2000.

The caveat is that it's only good for a single row, and it only works for UPDATE - if you're using DELETE, you'll still need the temp table and an OUTPUT clause.

Tagged as: No Comments