15.02.2015 Views

C# 4 and .NET 4

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

858 ❘ ChaPTer 30 cOre AdO.net<br />

GO<br />

Categories AS new<br />

WHERE old.CategoryID = new.CategoryID;<br />

code download StoredProcs.sql<br />

If you are used to Oracle stored procedures, SQL Server doesn’t exactly have the concept of OLD <strong>and</strong> NEW<br />

rows; instead, for an insert trigger there is an in-memory table called Inserted, <strong>and</strong> for deletes <strong>and</strong> updates<br />

the old rows are available within the Deleted table.<br />

This trigger retrieves the CategoryID of the record(s) affected <strong>and</strong> stores this together with the old <strong>and</strong> new<br />

value of the CategoryName column.<br />

Now, when you call your original stored procedure to insert a new CategoryID, you receive an identity<br />

value; however, this is no longer the identity value from the row inserted into the Categories table — it is<br />

now the new value generated for the row in the CategoryAudit table. Ouch!<br />

To view the problem first-h<strong>and</strong>, open a copy of SQL Server Enterprise Manager, <strong>and</strong> view the contents of<br />

the Categories table (see Figure 30-11).<br />

figure 30-11<br />

This lists all the categories in the Northwind database.<br />

The next identity value for the Categories table should be 9, so a new row can be inserted by executing the<br />

following code, to see what ID is returned:<br />

DECLARE @CatID int;<br />

EXECUTE CategoryInsert 'Pastries', 'Heaven Sent Food', @CatID OUTPUT;<br />

PRINT @CatID;<br />

The output value of this on a test PC was 1. If you look at the CategoryAudit table shown in<br />

Figure 30-12, you will find that this is the identity of the newly inserted audit record, not the identity of<br />

the category record created.<br />

The problem lies in the way that @@IDENTITY actually<br />

works. It returns the LAST identity value created by your<br />

session, so as shown in Figure 30-12, it isn’t completely<br />

reliable.<br />

figure 30-12<br />

Two other identity functions can be used instead of<br />

@@IDENTITY, but neither is free from possible problems. The first, SCOPE_IDENTITY(), returns the last<br />

identity value created within the current scope. SQL Server defines scope as a stored procedure, trigger, or<br />

function. This may work most of the time, but if for some reason someone adds another INSERT statement<br />

to the stored procedure, you can receive this value rather than the one you expected.<br />

The other identity function, IDENT_CURRENT(), returns the last identity value generated for a given table<br />

in any scope. For example, if two users were accessing SQL Server at exactly the same time, it might be<br />

possible to receive the other user’s generated identity value.<br />

As you might imagine, tracking down a problem of this nature is not easy. The moral of the story is to<br />

beware when using IDENTITY columns in SQL Server.<br />

www.it-ebooks.info

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!