OUTPUT Clause Basics (For Inserts and Deletes)

, 2017-05-02

When processing complex insert, update and delete statements it’s often useful to know exactly what has been changed, whether it’s for auditing purposes, or to return a value to a calling application (such as an ID, or other value following an insert, for example). The OUTPUT clause in T-SQL allows you to do just that, and it’s really, really straightforward….I’ll show you how!

Let’s start by creating a new table:

if object_id('tempdb..#outputexample') is not null drop table #outputexample;
go
create table #outputexample
(
       WidgetID int identity(1,1),
       WidgetName varchar(200),
       WidgetStatus varchar(10)
)

We will begin by populating this with a single row, and using the OUTPUT clause to return details on the row added:

insert #outputexample
output inserted.*
values
('Thingummybob','In Production')

In this really simplistic example you can see we added the OUTPUT clause directly after the insert statement, but before the actual change we wanted to make to the table.  You’ll also notice that we specified that we wanted to look at the inserted rows by prefixing the rest of the statement with the ‘inserted’ keyword.  In this example we followed this with * to return all columns (similar to SELECT *).

With this in mind (because SELECT * is naughty, ok?) we can be more specific about what we want to return:

insert #outputexample
output inserted.WidgetID, inserted.WidgetStatus
values
('Thingummybob','In Production')

And as you could expect, this would give us the WidgetID and WidgetStatus columns that were in the values added to the table. 

As you can see, the output clause is pretty much like applying a SELECT statement on the items that have been changed on the table in question. Let’s look at how this might work with delete.  For this example let’s add a number of items to the table so we’ve more to work with:

insert #outputexample
values
('Long Stand','In Production'),
('Tartan Paint','For Sale'),
('Glass Hammer','Discontinued'),
('Left Handed Screwdriver','Discontinued'),
('Elbow Grease','For Sale'),
('Sky Hooks','Discontinued')

I’m now going to delete all ‘Discontinued’ items, and use the OUTPUT clause to return a list of the deletions:

delete from #outputexample
output deleted.*
where WidgetStatus = 'Discontinued'

Again, the OUTPUT clause is positioned directly after the delete statement but before the conditions for the delete itself, and the rest of the clause is prefixed with the ‘delete’ keyword (and another naughty *).  As you can see this is also pretty much like writing a ‘SELECT *’ from the deleted values from the table, and we could/should once again substitute the deleted.* for a comma separated list of column names, or even calculated columns with aliases if we wanted.

Another useful thing about this technique is that you can insert your output into another table if you wish.  Look at the example below:-

if object_id('tempdb..#outputexample') is not null drop table #outputexample;
if object_id('tempdb..#deleteditems') is not null drop table #deleteditems;
go
create table #outputexample
(
       WidgetID int identity(1,1),
       WidgetName varchar(200),
       WidgetStatus varchar(20)
)

create table #deleteditems
(
       WidgetID int,
       WidgetName varchar(200),
       WidgetStatus varchar(20),
       DeletedDateTime datetime
)
insert #outputexample
values
('Long Stand','In Production'),
('Tartan Paint','For Sale'),
('Glass Hammer','Discontinued'),
('Left Handed Screwdriver','Discontinued'),
('Elbow Grease','For Sale'),
('Sky Hooks','Discontinued')
delete from #outputexample
output deleted.*, getdate()
into #deleteditems
where WidgetStatus = 'Discontinued'
select * from #deleteditems

In this case, I’ve created a table to store deleted item details, including a deleted date and time.  Using the output clause, I’ve been able to store the details of the deleted rows, including the date and time the deletion happened.  This is stupidly simple example, but something like this could be used for auditing purposes perhaps, if given more thought.

These were only very basic explanations of how the OUTPUT clause could be put to use, but as you can see it is quite a powerful command with multiple potential uses.  I encourage you to play around with this handy little technique and see what kinds of uses to which you can put it.

Rate

4.59 (22)

Share

Share

Rate

4.59 (22)

Related content

The DELETE statement in SQL Server

Of the big four DML statements in SQL Server, the DELETE is the one least written about. This is odd considering the extra power conferred on the statement by the addition of the WITH common_table_expression; and the OUTPUT clause that essentially allows you to move data from one table to another in one statement.

2010-12-13

6,506 reads

Deleting Large Number of Records

Often someone will try to perform a delete on a large number of records and run into a number of problems. Slow performance, log growth, and more. Lynn Pettis shows us how to better handle this situation in SQL Server 2000 and SQL Server 2005

3.11 (111)

2011-02-18 (first published: )

50,592 reads