<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://sqlblog.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Steve Kass</title><link>http://sqlblog.com/blogs/steve_kass/default.aspx</link><description>SQL MVP since 2002
Professor of Mathematics and Computer Science at Drew University</description><dc:language>en</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><item><title>How to convert Books Online ms-help: links to MSDN Library http: links [bookmarklet included]</title><link>http://sqlblog.com/blogs/steve_kass/archive/2009/08/05/how-to-convert-books-online-ms-help-links-to-msdn-library-http-links-bookmarklet-included.aspx</link><pubDate>Wed, 05 Aug 2009 03:11:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:15783</guid><dc:creator>skass</dc:creator><slash:comments>4</slash:comments><comments>http://sqlblog.com/blogs/steve_kass/comments/15783.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/steve_kass/commentrss.aspx?PostID=15783</wfw:commentRss><description>As you know, Books Online is available in two convenient locations. It's online as part of the MSDN Library, and it's offline as a Document Explorer help collection. Topics are accessible by URIs in each, but the URIs don't match. For example: Books Online...(&lt;a href="http://sqlblog.com/blogs/steve_kass/archive/2009/08/05/how-to-convert-books-online-ms-help-links-to-msdn-library-http-links-bookmarklet-included.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=15783" width="1" height="1"&gt;</description><category domain="http://sqlblog.com/blogs/steve_kass/archive/tags/bookmarklet/default.aspx">bookmarklet</category><category domain="http://sqlblog.com/blogs/steve_kass/archive/tags/Books+Online/default.aspx">Books Online</category><category domain="http://sqlblog.com/blogs/steve_kass/archive/tags/MSDN/default.aspx">MSDN</category><category domain="http://sqlblog.com/blogs/steve_kass/archive/tags/URL+translation/default.aspx">URL translation</category></item><item><title>DELETE FROM Where?</title><link>http://sqlblog.com/blogs/steve_kass/archive/2009/04/30/delete-from-where.aspx</link><pubDate>Thu, 30 Apr 2009 21:48:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:13678</guid><dc:creator>skass</dc:creator><slash:comments>10</slash:comments><comments>http://sqlblog.com/blogs/steve_kass/comments/13678.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/steve_kass/commentrss.aspx?PostID=13678</wfw:commentRss><description>&lt;P&gt;&lt;SPAN style="WIDOWS:2;TEXT-TRANSFORM:none;TEXT-INDENT:0px;BORDER-COLLAPSE:separate;FONT:16px 'Times New Roman';WHITE-SPACE:normal;ORPHANS:2;LETTER-SPACING:normal;WORD-SPACING:0px;-webkit-text-size-adjust:auto;-webkit-border-horizontal-spacing:0px;-webkit-border-vertical-spacing:0px;-webkit-text-decorations-in-effect:none;-webkit-text-stroke-width:0px;" class=Apple-style-span&gt;&lt;SPAN style="TEXT-ALIGN:left;FONT-FAMILY:Verdana;FONT-SIZE:11px;" class=Apple-style-span&gt;For years, SQL Server has supported a (second) FROM clause in UPDATE and DELETE statements. Its behavior isn't always deterministic, a fact Microsoft points out in the documentation. &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="WIDOWS:2;TEXT-TRANSFORM:none;TEXT-INDENT:0px;BORDER-COLLAPSE:separate;FONT:16px 'Times New Roman';WHITE-SPACE:normal;ORPHANS:2;LETTER-SPACING:normal;WORD-SPACING:0px;-webkit-text-size-adjust:auto;-webkit-border-horizontal-spacing:0px;-webkit-border-vertical-spacing:0px;-webkit-text-decorations-in-effect:none;-webkit-text-stroke-width:0px;" class=Apple-style-span&gt;&lt;SPAN style="TEXT-ALIGN:left;FONT-FAMILY:Verdana;FONT-SIZE:11px;" class=Apple-style-span&gt;Today, someone was surprised by&amp;nbsp;the basic semantics of DELETE .. FROM.&amp;nbsp;This probably happens a lot, but fortunately today's surprisee&amp;nbsp;posted &lt;A title="Connect item #436328" href="https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=436328"&gt;this Connect item&lt;/A&gt; because the following&amp;nbsp;statement didn't do what the documentation seemed to say it would:&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;SPAN style="WIDOWS:2;TEXT-TRANSFORM:none;TEXT-INDENT:0px;BORDER-COLLAPSE:separate;FONT:16px 'Times New Roman';WHITE-SPACE:normal;ORPHANS:2;LETTER-SPACING:normal;WORD-SPACING:0px;-webkit-text-size-adjust:auto;-webkit-border-horizontal-spacing:0px;-webkit-border-vertical-spacing:0px;-webkit-text-decorations-in-effect:none;-webkit-text-stroke-width:0px;" class=Apple-style-span&gt;&lt;SPAN style="TEXT-ALIGN:left;FONT-FAMILY:Verdana;FONT-SIZE:11px;" class=Apple-style-span&gt;&lt;FONT color=#0000ff&gt;
&lt;P&gt;DELETE&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;FROM&lt;/FONT&gt; t2&lt;BR&gt;&lt;FONT color=#0000ff&gt;FROM&lt;/FONT&gt; t1 &lt;FONT color=#0000ff&gt;AS&lt;/FONT&gt; t2&lt;/P&gt;
&lt;P&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="WIDOWS:2;TEXT-TRANSFORM:none;TEXT-INDENT:0px;BORDER-COLLAPSE:separate;FONT:16px 'Times New Roman';WHITE-SPACE:normal;ORPHANS:2;LETTER-SPACING:normal;WORD-SPACING:0px;-webkit-text-size-adjust:auto;-webkit-border-horizontal-spacing:0px;-webkit-border-vertical-spacing:0px;-webkit-text-decorations-in-effect:none;-webkit-text-stroke-width:0px;" class=Apple-style-span&gt;&lt;SPAN style="TEXT-ALIGN:left;FONT-FAMILY:Verdana;FONT-SIZE:11px;" class=Apple-style-span&gt;Quick now, what table does this truncate?&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="WIDOWS:2;TEXT-TRANSFORM:none;TEXT-INDENT:0px;BORDER-COLLAPSE:separate;FONT:16px 'Times New Roman';WHITE-SPACE:normal;ORPHANS:2;LETTER-SPACING:normal;WORD-SPACING:0px;-webkit-text-size-adjust:auto;-webkit-border-horizontal-spacing:0px;-webkit-border-vertical-spacing:0px;-webkit-text-decorations-in-effect:none;-webkit-text-stroke-width:0px;" class=Apple-style-span&gt;&lt;SPAN style="TEXT-ALIGN:left;FONT-FAMILY:Verdana;FONT-SIZE:11px;" class=Apple-style-span&gt;You're in good company if you said t2, which is the wrong answer. &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="WIDOWS:2;TEXT-TRANSFORM:none;TEXT-INDENT:0px;BORDER-COLLAPSE:separate;FONT:16px 'Times New Roman';WHITE-SPACE:normal;ORPHANS:2;LETTER-SPACING:normal;WORD-SPACING:0px;-webkit-text-size-adjust:auto;-webkit-border-horizontal-spacing:0px;-webkit-border-vertical-spacing:0px;-webkit-text-decorations-in-effect:none;-webkit-text-stroke-width:0px;" class=Apple-style-span&gt;&lt;SPAN style="TEXT-ALIGN:left;FONT-FAMILY:Verdana;FONT-SIZE:11px;" class=Apple-style-span&gt;The statement truncates t1, however, not t2. In fact, this &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="WIDOWS:2;TEXT-TRANSFORM:none;TEXT-INDENT:0px;BORDER-COLLAPSE:separate;FONT:16px 'Times New Roman';WHITE-SPACE:normal;ORPHANS:2;LETTER-SPACING:normal;WORD-SPACING:0px;-webkit-text-size-adjust:auto;-webkit-border-horizontal-spacing:0px;-webkit-border-vertical-spacing:0px;-webkit-text-decorations-in-effect:none;-webkit-text-stroke-width:0px;" class=Apple-style-span&gt;&lt;SPAN style="TEXT-ALIGN:left;FONT-FAMILY:Verdana;FONT-SIZE:11px;" class=Apple-style-span&gt;DELETE statement contains no reference to the table t2, assuming there even is one. Here, t2 is only an alias, and the statement is semantically identical to&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;DELETE&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;FROM&lt;/FONT&gt; ThisIsAnAliasNotATable&lt;BR&gt;&lt;FONT color=#0000ff&gt;FROM&lt;/FONT&gt; t1 &lt;FONT color=#0000ff&gt;AS&lt;/FONT&gt; ThisIsAnAliasNotATable&lt;/P&gt;
&lt;P&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="WIDOWS:2;TEXT-TRANSFORM:none;TEXT-INDENT:0px;BORDER-COLLAPSE:separate;FONT:16px 'Times New Roman';WHITE-SPACE:normal;ORPHANS:2;LETTER-SPACING:normal;WORD-SPACING:0px;-webkit-text-size-adjust:auto;-webkit-border-horizontal-spacing:0px;-webkit-border-vertical-spacing:0px;-webkit-text-decorations-in-effect:none;-webkit-text-stroke-width:0px;" class=Apple-style-span&gt;&lt;SPAN style="TEXT-ALIGN:left;FONT-FAMILY:Verdana;FONT-SIZE:11px;" class=Apple-style-span&gt;When there are two FROM clauses in a DELETE statement, the first FROM clause is interpreted in the context of the table source defined by the second one, which is analogous to how SELECT works. The following query selects rows from t1, not t2, and that's no surprise:&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;SPAN style="WIDOWS:2;TEXT-TRANSFORM:none;TEXT-INDENT:0px;BORDER-COLLAPSE:separate;FONT:16px 'Times New Roman';WHITE-SPACE:normal;ORPHANS:2;LETTER-SPACING:normal;WORD-SPACING:0px;-webkit-text-size-adjust:auto;-webkit-border-horizontal-spacing:0px;-webkit-border-vertical-spacing:0px;-webkit-text-decorations-in-effect:none;-webkit-text-stroke-width:0px;" class=Apple-style-span&gt;&lt;SPAN style="TEXT-ALIGN:left;FONT-FAMILY:Verdana;FONT-SIZE:11px;" class=Apple-style-span&gt;&lt;FONT color=#0000ff&gt;
&lt;P&gt;SELECT&lt;/FONT&gt; t2&lt;FONT color=#808080&gt;.&lt;/FONT&gt;a&lt;BR&gt;&lt;FONT color=#0000ff&gt;FROM&lt;/FONT&gt; t1 &lt;FONT color=#0000ff&gt;AS&lt;/FONT&gt; t2&lt;/P&gt;
&lt;P&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="WIDOWS:2;TEXT-TRANSFORM:none;TEXT-INDENT:0px;BORDER-COLLAPSE:separate;FONT:16px 'Times New Roman';WHITE-SPACE:normal;ORPHANS:2;LETTER-SPACING:normal;WORD-SPACING:0px;-webkit-text-size-adjust:auto;-webkit-border-horizontal-spacing:0px;-webkit-border-vertical-spacing:0px;-webkit-text-decorations-in-effect:none;-webkit-text-stroke-width:0px;" class=Apple-style-span&gt;&lt;SPAN style="TEXT-ALIGN:left;FONT-FAMILY:Verdana;FONT-SIZE:11px;" class=Apple-style-span&gt;&lt;SPAN style="WIDOWS:2;TEXT-TRANSFORM:none;TEXT-INDENT:0px;BORDER-COLLAPSE:separate;FONT:16px 'Times New Roman';WHITE-SPACE:normal;ORPHANS:2;LETTER-SPACING:normal;WORD-SPACING:0px;-webkit-text-size-adjust:auto;-webkit-border-horizontal-spacing:0px;-webkit-border-vertical-spacing:0px;-webkit-text-decorations-in-effect:none;-webkit-text-stroke-width:0px;" class=Apple-style-span&gt;&lt;SPAN style="TEXT-ALIGN:left;FONT-FAMILY:Verdana;FONT-SIZE:11px;" class=Apple-style-span&gt;If you think about it, you should&amp;nbsp;agree that different behavior for DELETE would be very bad. If SQL Server produced what Vitaliy expected, someone could create tables with names used somewhere as aliases, and cause UPDATE and DELETE statements to stop updating the tables they were supposed to update. &lt;/SPAN&gt;&lt;/SPAN&gt;What makes the DELETE behavior more confusing than the SELECT behavior is the fact that in the case of DELETE, the keyword FROM can be used twice. It you write DELETE .. FROM statements with two FROMs,&amp;nbsp;remember that the bottom FROM clause is the "outer" one in the sense of scope. It should be considered first, as is clearer in this DELETE statement, which is equivalent to the one that suprised Vitaliy:&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;SPAN style="WIDOWS:2;TEXT-TRANSFORM:none;TEXT-INDENT:0px;BORDER-COLLAPSE:separate;FONT:16px 'Times New Roman';WHITE-SPACE:normal;ORPHANS:2;LETTER-SPACING:normal;WORD-SPACING:0px;-webkit-text-size-adjust:auto;-webkit-border-horizontal-spacing:0px;-webkit-border-vertical-spacing:0px;-webkit-text-decorations-in-effect:none;-webkit-text-stroke-width:0px;" class=Apple-style-span&gt;&lt;SPAN style="TEXT-ALIGN:left;FONT-FAMILY:Verdana;FONT-SIZE:11px;" class=Apple-style-span&gt;&lt;FONT color=#0000ff&gt;
&lt;P&gt;WITH&lt;/FONT&gt; t2 &lt;FONT color=#0000ff&gt;AS &lt;/FONT&gt;&lt;FONT color=#808080&gt;(&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#0000ff&gt;SELECT&lt;/FONT&gt;&amp;nbsp;* &lt;FONT color=#0000ff&gt;FROM&lt;/FONT&gt; t1&lt;BR&gt;&lt;FONT color=#808080&gt;)&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#0000ff&gt;DELETE&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;FROM&lt;/FONT&gt; t2&lt;/P&gt;
&lt;P&gt;For the record, this CTE-based DELETE is just as non-standard as the DELETE .. FROM, but it's less confusing. If you can't easily (or effeciently) avoid the use of DELETE .. FROM, consider rewriting DELETE .. FROM as a CTE to reduce the chance of confusion.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="WIDOWS:2;TEXT-TRANSFORM:none;TEXT-INDENT:0px;BORDER-COLLAPSE:separate;FONT:16px 'Times New Roman';WHITE-SPACE:normal;ORPHANS:2;LETTER-SPACING:normal;WORD-SPACING:0px;-webkit-text-size-adjust:auto;-webkit-border-horizontal-spacing:0px;-webkit-border-vertical-spacing:0px;-webkit-text-decorations-in-effect:none;-webkit-text-stroke-width:0px;" class=Apple-style-span&gt;&lt;SPAN style="TEXT-ALIGN:left;FONT-FAMILY:Verdana;FONT-SIZE:11px;" class=Apple-style-span&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=13678" width="1" height="1"&gt;</description><category domain="http://sqlblog.com/blogs/steve_kass/archive/tags/Connect/default.aspx">Connect</category><category domain="http://sqlblog.com/blogs/steve_kass/archive/tags/DELETE/default.aspx">DELETE</category><category domain="http://sqlblog.com/blogs/steve_kass/archive/tags/nonstandard/default.aspx">nonstandard</category><category domain="http://sqlblog.com/blogs/steve_kass/archive/tags/T-SQL/default.aspx">T-SQL</category><category domain="http://sqlblog.com/blogs/steve_kass/archive/tags/T-SQL+language+extensions/default.aspx">T-SQL language extensions</category></item><item><title>It's 2008, and @@ROWCOUNT ain't what it used to be. Don't use it in triggers.</title><link>http://sqlblog.com/blogs/steve_kass/archive/2009/04/29/It_2700_s-2008-and-rowcount-ain_2700_t-what-it-used-to-be.-Don_2700_t-use-it-in-triggers_2100_.aspx</link><pubDate>Wed, 29 Apr 2009 04:57:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:13623</guid><dc:creator>skass</dc:creator><slash:comments>5</slash:comments><comments>http://sqlblog.com/blogs/steve_kass/comments/13623.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/steve_kass/commentrss.aspx?PostID=13623</wfw:commentRss><description>&lt;SPAN style="WIDOWS:2;TEXT-TRANSFORM:none;TEXT-INDENT:0px;BORDER-COLLAPSE:separate;FONT:16px 'Times New Roman';WHITE-SPACE:normal;ORPHANS:2;LETTER-SPACING:normal;WORD-SPACING:0px;-webkit-text-size-adjust:auto;-webkit-border-horizontal-spacing:0px;-webkit-border-vertical-spacing:0px;-webkit-text-decorations-in-effect:none;-webkit-text-stroke-width:0px;" class=Apple-style-span&gt;
&lt;DIV style="PADDING-BOTTOM:8px;PADDING-LEFT:8px;PADDING-RIGHT:8px;FONT-FAMILY:Arial, Helvetica, sans-serif;FONT-SIZE:10pt;PADDING-TOP:8px;"&gt;
&lt;P&gt;During SQL Server 2008 beta testing, Aaron Bertrand &lt;A title="Connect Item 298395" href="https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=298395"&gt;noted&lt;/A&gt; that the value of @@rowcount inside a trigger could be unexpected, if the triggering statement was MERGE.&lt;/P&gt;
&lt;P&gt;The consequences of this can be pretty bad, but fortunately there's a simple workaround. You need to do something if anyone might invoke MERGE against tables with triggers that contain @@rowcount checks &lt;/P&gt;
&lt;P&gt;A MERGE statement can cause as many as three triggers to fire. Within each of them, the value of @@rowcount is the number of rows affected by the entire MERGE statement, i.e. the total number rows inserted, updated, &lt;I&gt;or&lt;/I&gt; deleted by the various merge clauses.&lt;/P&gt;
&lt;P&gt;Books Online mentions this in the article on MERGE: &lt;I&gt;When used after MERGE, @@ROWCOUNT (Transact-SQL) returns the total number of rows inserted, updated, and deleted to the client.&lt;/I&gt;&lt;/P&gt;
&lt;P&gt;Elsewhere, however, Books Online continues to give old advice that as of 2008 is not good advice. For example, in the article Multirow considerations for DML triggers, Books Online says, &lt;I&gt;For example, the&lt;SPAN class=Apple-converted-space&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;@@ROWCOUNT&lt;/CODE&gt;&lt;SPAN class=Apple-converted-space&gt;&amp;nbsp;&lt;/SPAN&gt;function can be used in the logic of the trigger to distinguish between a single and a multirow insert.&lt;/I&gt;&lt;/P&gt;
&lt;P&gt;Not so, I'm afraid. The value of @@rowcount in an INSERT trigger, say, will always be at least equal to the number of rows inserted, but it can be greater. For example, a MERGE statement could have an INSERT action that doesn't occur, but an UPDATE one that updates 3 rows. The INSERT trigger will be called, because the MERGE statement's INSERT section "inserted zero rows."&lt;/P&gt;
&lt;P&gt;Here's an example from AdventureWorks2008 to show what can go wrong.&lt;/P&gt;
&lt;P&gt;I've added a GrandTotal table containing one row and column. GrandTotal.gt is supposed to keep track of the grand total of all purchase SubTotals.&lt;/P&gt;
&lt;P&gt;This code creates the table and gives it a value that's initially correct for the data in AdventureWorks2008:&lt;/P&gt;&lt;FONT color=#0000ff&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT color=#0000ff&gt;USE&lt;/FONT&gt; AdventureWorks2008&lt;FONT color=#808080&gt;;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;GO&lt;BR&gt;&amp;nbsp; CREATE&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;TABLE&lt;/FONT&gt; GrandTotal&lt;FONT color=#808080&gt;(&lt;BR&gt;&lt;/FONT&gt;&amp;nbsp; gt &lt;FONT color=#0000ff&gt;DECIMAL&lt;/FONT&gt;&lt;FONT color=#808080&gt;(&lt;/FONT&gt;18&lt;FONT color=#808080&gt;,&lt;/FONT&gt;2&lt;FONT color=#808080&gt;)&lt;BR&gt;);&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;INSERT&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;INTO&lt;/FONT&gt; GrandTotal;&lt;BR&gt;&lt;FONT color=#0000ff&gt;SELECT&lt;/FONT&gt; &lt;FONT color=#ff00ff&gt;sum&lt;/FONT&gt;&lt;FONT color=#808080&gt;(&lt;/FONT&gt;SubTotal&lt;FONT color=#808080&gt;);&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;FROM&lt;/FONT&gt; Purchasing&lt;FONT color=#808080&gt;.&lt;/FONT&gt;PurchaseOrderHeader&lt;FONT color=#808080&gt;;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;GO&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#0000ff&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;&lt;FONT color=#000000&gt;This code creates a trigger to update the grand total whenever new line items are inserted into the table:&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#0000ff&gt;CREATE&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;TRIGGER&lt;/FONT&gt; NewPODetail3&lt;BR&gt;&lt;FONT color=#0000ff&gt;ON&lt;/FONT&gt; Purchasing&lt;FONT color=#808080&gt;.&lt;/FONT&gt;PurchaseOrderDetail&lt;BR&gt;&lt;FONT color=#0000ff&gt;FOR&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;INSERT&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;AS&lt;BR&gt;IF&lt;/FONT&gt; &lt;FONT color=#ff00ff&gt;@@ROWCOUNT&lt;/FONT&gt; &lt;FONT color=#808080&gt;&amp;gt;&lt;/FONT&gt; 0&lt;BR&gt;&lt;FONT color=#0000ff&gt;UPDATE&lt;/FONT&gt; GrandTotal &lt;FONT color=#0000ff&gt;SET&lt;BR&gt;&lt;/FONT&gt;gt &lt;FONT color=#808080&gt;+=&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; &lt;/FONT&gt;&lt;FONT color=#808080&gt;(&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;SELECT&lt;/FONT&gt; &lt;FONT color=#ff00ff&gt;SUM&lt;/FONT&gt;&lt;FONT color=#808080&gt;(&lt;/FONT&gt;LineTotal&lt;FONT color=#808080&gt;) &lt;/FONT&gt;&lt;FONT color=#0000ff&gt;FROM&lt;/FONT&gt; inserted);&lt;BR&gt;&lt;FONT color=#0000ff&gt;GO&lt;/FONT&gt;&lt;/P&gt;&lt;FONT color=#0000ff&gt;&lt;/FONT&gt;
&lt;DIV&gt;
&lt;P&gt;&lt;FONT color=#0000ff&gt;&lt;FONT color=#000000&gt;And this MERGE statement (enclosed in a rolled-back transaction here so that no data in the database is modified by this test script) has the unintended result of updating the grand total from $63,791,994.84 to NULL. &lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#0000ff&gt;begin&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;tran&lt;BR&gt;select&lt;/FONT&gt; &lt;FONT color=#808080&gt;*&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;From&lt;/FONT&gt; GrandTotal&lt;FONT color=#808080&gt;;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;merge&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;into&lt;/FONT&gt; Purchasing&lt;FONT color=#808080&gt;.&lt;/FONT&gt;PurchaseOrderDetail &lt;FONT color=#0000ff&gt;as&lt;/FONT&gt; P&lt;BR&gt;&lt;FONT color=#0000ff&gt;using &lt;/FONT&gt;&lt;FONT color=#808080&gt;(&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp; select&lt;/FONT&gt; 2&lt;FONT color=#808080&gt;,&lt;/FONT&gt;&lt;FONT color=#ff0000&gt;'20010715'&lt;/FONT&gt;&lt;FONT color=#808080&gt;,&lt;/FONT&gt;100&lt;FONT color=#808080&gt;,&lt;/FONT&gt;318&lt;FONT color=#808080&gt;,&lt;/FONT&gt;100&lt;FONT color=#808080&gt;,&lt;/FONT&gt;318&lt;FONT color=#808080&gt;,&lt;/FONT&gt;0&lt;FONT color=#808080&gt;,&lt;/FONT&gt;&lt;FONT color=#ff0000&gt;'20090101'&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#808080&gt;)&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;as&lt;/FONT&gt; T&lt;FONT color=#808080&gt;(&lt;/FONT&gt;PurchaseOrderID&lt;FONT color=#808080&gt;,&lt;/FONT&gt;DueDate&lt;FONT color=#808080&gt;,&lt;/FONT&gt;OrderQty&lt;FONT color=#808080&gt;,&lt;/FONT&gt;ProductID&lt;FONT color=#808080&gt;,&lt;/FONT&gt;UnitPrice&lt;FONT color=#808080&gt;,&lt;/FONT&gt;ReceivedQty&lt;FONT color=#808080&gt;,&lt;/FONT&gt;RejectedQty&lt;FONT color=#808080&gt;,&lt;/FONT&gt;ModifiedDate&lt;FONT color=#808080&gt;)&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;on&lt;/FONT&gt; T&lt;FONT color=#808080&gt;.&lt;/FONT&gt;PurchaseOrderID &lt;FONT color=#808080&gt;=&lt;/FONT&gt; P&lt;FONT color=#808080&gt;.&lt;/FONT&gt;PurchaseOrderID&lt;BR&gt;&lt;FONT color=#0000ff&gt;when&lt;/FONT&gt; &lt;FONT color=#808080&gt;matched&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;then&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp; update&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;set&lt;/FONT&gt; ModifiedDate &lt;FONT color=#808080&gt;=&lt;/FONT&gt; T&lt;FONT color=#808080&gt;.&lt;/FONT&gt;ModifiedDate&lt;BR&gt;&lt;FONT color=#0000ff&gt;when&lt;/FONT&gt; &lt;FONT color=#808080&gt;not&lt;/FONT&gt; &lt;FONT color=#808080&gt;matched&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;by&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;target&lt;/FONT&gt; &lt;FONT color=#808080&gt;and&lt;/FONT&gt; PurchaseOrderID &lt;FONT color=#808080&gt;&amp;lt;&lt;/FONT&gt; 0 &lt;FONT color=#0000ff&gt;then&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#0000ff&gt;insert &lt;/FONT&gt;&lt;FONT color=#808080&gt;(&lt;/FONT&gt;PurchaseOrderID&lt;FONT color=#808080&gt;,&lt;/FONT&gt;DueDate&lt;FONT color=#808080&gt;,&lt;/FONT&gt;OrderQty&lt;FONT color=#808080&gt;,&lt;/FONT&gt;ProductID&lt;FONT color=#808080&gt;,&lt;/FONT&gt;UnitPrice&lt;FONT color=#808080&gt;,&lt;/FONT&gt;ReceivedQty&lt;FONT color=#808080&gt;,&lt;/FONT&gt;RejectedQty&lt;FONT color=#808080&gt;,&lt;/FONT&gt;ModifiedDate&lt;FONT color=#808080&gt;)&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#0000ff&gt;values &lt;/FONT&gt;&lt;FONT color=#808080&gt;(&lt;/FONT&gt;3&lt;FONT color=#808080&gt;,&lt;/FONT&gt;&lt;FONT color=#ff0000&gt;'20010715'&lt;/FONT&gt;&lt;FONT color=#808080&gt;,&lt;/FONT&gt;100&lt;FONT color=#808080&gt;,&lt;/FONT&gt;318&lt;FONT color=#808080&gt;,&lt;/FONT&gt;100&lt;FONT color=#808080&gt;,&lt;/FONT&gt;318&lt;FONT color=#808080&gt;,&lt;/FONT&gt;0&lt;FONT color=#808080&gt;,&lt;/FONT&gt;&lt;FONT color=#ff0000&gt;'20090101'&lt;/FONT&gt;&lt;FONT color=#808080&gt;);&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;select&lt;/FONT&gt; &lt;FONT color=#808080&gt;*&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;From&lt;/FONT&gt; GrandTotal&lt;BR&gt;&lt;FONT color=#0000ff&gt;rollback&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;tran&lt;/FONT&gt;&lt;FONT color=#808080&gt;;&lt;BR&gt;&lt;/P&gt;&lt;/FONT&gt;
&lt;P&gt;Oops.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;MERGE is only beginning to get&amp;nbsp;used, and for a variety of triggers, a too-large @@rowcount won't cause a problem. But I think the number of people who might get caught by this problem will grow.&lt;/P&gt;
&lt;P&gt;Don't use @@rowcount in triggers, unless you're certain it doesn't cause problems if it's higher than the real rowcount you want (which might be zero). As an alternative, Itzik suggested to me this (for INSERT; the others are similar):&lt;/P&gt;&lt;FONT color=#0000ff&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT color=#0000ff&gt;declare&lt;/FONT&gt; @rc &lt;FONT color=#0000ff&gt;int&lt;/FONT&gt;&lt;FONT color=#808080&gt;;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;with&lt;/FONT&gt; Two &lt;FONT color=#0000ff&gt;as &lt;/FONT&gt;&lt;FONT color=#808080&gt;(&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;select&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;top &lt;/FONT&gt;&lt;FONT color=#808080&gt;(&lt;/FONT&gt;2&lt;FONT color=#808080&gt;)&lt;/FONT&gt; &lt;FONT color=#808080&gt;*&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;from&lt;/FONT&gt; inserted&lt;FONT color=#808080&gt;)&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;select&lt;/FONT&gt; @rc &lt;FONT color=#808080&gt;=&lt;/FONT&gt; &lt;FONT color=#ff00ff&gt;count&lt;/FONT&gt;&lt;FONT color=#808080&gt;(*)&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;from&lt;/FONT&gt; Two&lt;FONT color=#808080&gt;;&lt;/FONT&gt;&lt;/P&gt;&lt;FONT color=#808080&gt;&lt;/FONT&gt;&lt;/DIV&gt;The value of @rc will then be 0, 1, or 2, depending on whether 0, 1, or more than 1 rows were inserted.&lt;/DIV&gt;
&lt;P&gt;Steve Kass&lt;BR&gt;&lt;A href="http://www.stevekass.com/"&gt;http://www.stevekass.com&lt;/A&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=13623" width="1" height="1"&gt;</description><category domain="http://sqlblog.com/blogs/steve_kass/archive/tags/_40004000_rowcount/default.aspx">@@rowcount</category><category domain="http://sqlblog.com/blogs/steve_kass/archive/tags/MERGE/default.aspx">MERGE</category><category domain="http://sqlblog.com/blogs/steve_kass/archive/tags/SQL+Server+2008/default.aspx">SQL Server 2008</category><category domain="http://sqlblog.com/blogs/steve_kass/archive/tags/Triggers/default.aspx">Triggers</category></item></channel></rss>