Search This Blog

Friday, June 25, 2010

Output Clause:

Output is a new clause which can be paired off with Insert, Update & Delete statements to get the before and after image of the date being modified. It basically uses 2 magic tables
called as Inserted, Deleted for its operation.

Inserted table would contain a row for each row that is inserted and deleted table would contain a row each row that is deleted whereas both inserted and deleted would contain 1
row for row which is updated where the deleted holds the pre-image of data and inserted holds the new data that is inserted.

For Ex:
Col1 Col2
1 Peter

So if I update Peter to Peter Drucker then inserted table would have(Post Image)
Col1 Col2
1 Peter Drucker

And Deleted table would have(pre-image)
Col1 Col2
1 Peter

This feature was basically available only inside Triggers in SQL 2000, but however in SQL 2005 it is exposed and can be used even inside a stored procedure.

The ability to immediately access data changes without requiring additional reads from the database can enhance application throughput. When data modification statements
are executed in SQL Server 2005, you can capture the data that has been modified and store it for use in subsequent transactions.

One can use this technique
ü Trips to database from .Net or Java application to the database is reduced as its combined with INSERT/UPDATE/DELETE
ü To prevent the unnecessary reading of your online transaction processing (OLTP) tables which enhances application performance.
ü To implement custom data auditing without the use of triggers.

Let us see some examples on how to use various OUTPUT clauses.

Using Output clause to return the last value inserted into Identity, which is possible only by means of executing @@IDENTITY clause in SQL 2000

CREATE TABLE [dbo].[DOCS_HISTORY]
( [DOC_ID] [int] IDENTITY(1,1) NOT NULL,
[DOC_NAME] [varchar](100) )

INSERT INTO [DOCS_HISTORY]
OUTPUT INSERTED.[DOC_ID],INSERTED.[DOC_NAME]
SELECT 'test docs'

Using Output and Output INTO to show output and capture befor and after image to audit table

DECLARE @Tbl_Docs TABLE
( [DOC_ID_NEW] INT
, [DOC_NAME_NEW] VARCHAR(100),
[DOC_ID_OLD] INT ,
[DOC_NAME_OLD] VARCHAR(100),
CR_DATE DATETIME)

UPDATE [DOCS_HISTORY]
SET DOC_NAME = 'test documents'
OUTPUT INSERTED.[DOC_ID],
INSERTED.[DOC_NAME],
DELETED.[DOC_ID],
DELETED.[DOC_NAME],
GETDATE()
INTO @Tbl_Docs
OUTPUT INSERTED.[DOC_ID],
INSERTED.[DOC_NAME],
DELETED.[DOC_ID],
DELETED.[DOC_NAME]
WHERE DOC_ID = 100001

This is a very useful feature for auditing the pre and post image of data which was only possible by means of trigger in SQL 2000

Similarly OUTPUT can be used with DELETE statement as well to capture the data that was deleted from DELETED table.

5 comments:

Anonymous said...

Vivek :
So does the output of the Output clause just come to the console or can it be put into a variable as well (without requiring to put it into a table)?

Ganesh Jayaraman said...

That’s a good question. It doesn’t allow you to store data directly to variable but however we can fire a select from table variable to get the output which would be faster again with normal select from
table as it read from memory and not physical file, so trips to database tables is only once.

Anonymous said...

Vivek:
So if we just do OUTPUT, it “prints” it on to the console? Besides outputting to a table, there is no other way to access the values from within a java application connecting and executing queries on SQL. Am I right?

Ganesh Jayaraman said...

It selects data just like a normal SELECT statement and not as PRINT statement.

To know the difference between SELECT and PRINT just execute this below statement in SQL Server Management Studio in Grid Mode

declare @a int
select @a = 5
select @a
print @a + 5

You will see Select statement in results pane and PRINT in messages pane, anything which comes in Results can be captured in Front End applications like Java,Dot Net

And so in .Net we can capture the same as that is again a recordset(with 1 row and 1 or more columns) and values can be read just like reading a variable output or recordset output. Java I am not sure whether we can capture that and we may need to explore more on that.

Anonymous said...

Vivek:
Ok got it! So it comes back as a result-set like any other select queries.