<?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>Search results matching tag 'Bugs'</title><link>http://sqlblog.com/search/SearchResults.aspx?o=DateDescending&amp;tag=Bugs&amp;orTags=0</link><description>Search results matching tag 'Bugs'</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><item><title>Incorrect Results with Indexed Views</title><link>http://sqlblog.com/blogs/paul_white/archive/2013/02/05/incorrect-results-with-indexed-views.aspx</link><pubDate>Tue, 05 Feb 2013 22:18:11 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:47500</guid><dc:creator>Paul White</dc:creator><description>&lt;hr /&gt;&lt;font size="3" face="Calibri"&gt;&lt;em&gt;Summary: If you use MERGE, indexed views and foreign keys, your queries can return incorrect results.&lt;/em&gt;&lt;/font&gt;   &lt;br /&gt;  &lt;hr /&gt;  &lt;p&gt;&lt;font size="3" face="Calibri"&gt;Microsoft have &lt;a href="http://support.microsoft.com/kb/2756471" target="_blank"&gt;released a fix&lt;/a&gt; for incorrect results returned when querying an indexed view. &lt;/font&gt;&lt;font size="3" face="Calibri"&gt;The problem applies to:&lt;/font&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;font size="3" face="Calibri"&gt;&lt;strong&gt;SQL Server 2012&lt;/strong&gt;&lt;/font&gt; &lt;/li&gt;    &lt;li&gt;&lt;font size="3" face="Calibri"&gt;&lt;strong&gt;SQL Server 2008 R2&lt;/strong&gt;&lt;/font&gt; &lt;/li&gt;    &lt;li&gt;&lt;font size="3" face="Calibri"&gt;&lt;strong&gt;SQL Server 2008&lt;/strong&gt;&lt;/font&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;font size="3" face="Calibri"&gt;The &lt;a href="http://support.microsoft.com/kb/2756471" target="_blank"&gt;Knowledge Base article&lt;/a&gt; does not go into much detail, or provide a reproduction script, but this blog entry does :)&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="3" face="Calibri"&gt;The KB does say that reproducing the bug requires these features:&lt;/font&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;font size="3" face="Calibri"&gt;An indexed view on two tables that have a foreign key relationship&lt;/font&gt; &lt;/li&gt;    &lt;li&gt;&lt;font size="3" face="Calibri"&gt;An update performed against the base tables&lt;/font&gt; &lt;/li&gt;    &lt;li&gt;&lt;font size="3" face="Calibri"&gt;A query executed against the indexed view using a NOEXPAND hint&lt;/font&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;font size="3" face="Calibri"&gt;There are two important details I would like to add right away:&lt;/font&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;font size="3" face="Calibri"&gt;The &lt;a href="http://msdn.microsoft.com/en-us/library/ms181714.aspx" target="_blank"&gt;NOEXPAND&lt;/a&gt; hint is &lt;strong&gt;not required&lt;/strong&gt; to reproduce the bug on Enterprise Edition&lt;/font&gt; &lt;/li&gt;    &lt;li&gt;&lt;font size="3" face="Calibri"&gt;The update must be performed by a &lt;a href="http://technet.microsoft.com/en-us/library/bb510625.aspx" target="_blank"&gt;MERGE&lt;/a&gt; statement&lt;/font&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;font size="3" face="Calibri"&gt;The fix is available in the following cumulative update packages:&lt;/font&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font size="3" face="Calibri"&gt;&lt;a href="http://support.microsoft.com/kb/2790947" target="_blank"&gt;Cumulative Update 2 for SQL Server 2012 SP1&lt;/a&gt; [build 11.0.3339]         &lt;br /&gt;&lt;/font&gt;&lt;font size="3" face="Calibri"&gt;&lt;a href="http://support.microsoft.com/kb/2777772" target="_blank"&gt;Cumulative Update 5 for SQL Server 2012 RTM&lt;/a&gt; [build 11.0.2395]         &lt;br /&gt;&lt;/font&gt;&lt;font size="3" face="Calibri"&gt;&lt;a href="http://support.microsoft.com/kb/2777358" target="_blank"&gt;Cumulative Update 4 for SQL Server 2008 R2 SP2&lt;/a&gt; [build 10.50.4270]         &lt;br /&gt;&lt;/font&gt;&lt;font size="3" face="Calibri"&gt;&lt;a href="http://support.microsoft.com/kb/2783135" target="_blank"&gt;Cumulative Update 10 for SQL Server 2008 R2 SP1&lt;/a&gt; [build 10.50.2868]         &lt;br /&gt;&lt;/font&gt;&lt;font size="3" face="Calibri"&gt;&lt;a href="http://support.microsoft.com/kb/2771833" target="_blank"&gt;Cumulative Update 8 for SQL Server 2008 SP3&lt;/a&gt; [build 10.00.5828]&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;font size="3" face="Calibri"&gt;No service pack contains this fix, you must apply one of the hotfix packages above.&lt;/font&gt;&lt;/p&gt;  &lt;h2&gt;Steps to Reproduce&lt;/h2&gt;  &lt;p&gt;&lt;font size="3" face="Calibri"&gt;The first thing we will need is two tables:&lt;/font&gt;&lt;/p&gt;  &lt;div id="codeSnippetWrapper" style="overflow:auto;cursor:text;font-size:8pt;border-top:silver 1px solid;font-family:'Courier New', courier, monospace;border-right:silver 1px solid;border-bottom:silver 1px solid;padding-bottom:4px;direction:ltr;text-align:left;padding-top:4px;padding-left:4px;margin:20px 0px 10px;border-left:silver 1px solid;line-height:12pt;padding-right:4px;max-height:300px;width:97.5%;background-color:#f4f4f4;"&gt;   &lt;div id="codeSnippet" style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;     &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;&lt;span style="color:#0000ff;"&gt;CREATE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;TABLE&lt;/span&gt; dbo.Parent &lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;(&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;    parent_id &lt;span style="color:#0000ff;"&gt;integer&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;IDENTITY&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;NOT&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;NULL&lt;/span&gt;,&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;    &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;varchar&lt;/span&gt;(20) &lt;span style="color:#0000ff;"&gt;NOT&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;NULL&lt;/span&gt;,&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;    &lt;span style="color:#0000ff;"&gt;CONSTRAINT&lt;/span&gt; PK_Parent_id &lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;        &lt;span style="color:#0000ff;"&gt;PRIMARY&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;KEY&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;CLUSTERED&lt;/span&gt; (parent_id)&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;);&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;&lt;span style="color:#0000ff;"&gt;GO&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;&lt;span style="color:#0000ff;"&gt;CREATE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;TABLE&lt;/span&gt; dbo.Child&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;(&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;    child_id &lt;span style="color:#0000ff;"&gt;integer&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;IDENTITY&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;NOT&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;NULL&lt;/span&gt;,&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;    parent_id &lt;span style="color:#0000ff;"&gt;integer&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;NOT&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;NULL&lt;/span&gt;,&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;    &lt;span style="color:#0000ff;"&gt;CONSTRAINT&lt;/span&gt; PK_Child_id &lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;        &lt;span style="color:#0000ff;"&gt;PRIMARY&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;KEY&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;CLUSTERED&lt;/span&gt; (child_id)&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;);&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;And a few rows of data:&lt;/font&gt;&lt;/p&gt;

&lt;div id="codeSnippetWrapper" style="overflow:auto;cursor:text;font-size:8pt;border-top:silver 1px solid;font-family:'Courier New', courier, monospace;border-right:silver 1px solid;border-bottom:silver 1px solid;padding-bottom:4px;direction:ltr;text-align:left;padding-top:4px;padding-left:4px;margin:20px 0px 10px;border-left:silver 1px solid;line-height:12pt;padding-right:4px;max-height:200px;width:97.5%;background-color:#f4f4f4;"&gt;
  &lt;div id="codeSnippet" style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;
    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;INSERT dbo.Child (parent_id)&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;New&lt;/span&gt;.parent_id &lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;&lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; &lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;    (&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;    INSERT Parent &lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;    &lt;span style="color:#0000ff;"&gt;OUTPUT&lt;/span&gt; inserted.parent_id &lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;    &lt;span style="color:#0000ff;"&gt;VALUES&lt;/span&gt; &lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;        (&lt;span style="color:#006080;"&gt;'Apple'&lt;/span&gt;), &lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;        (&lt;span style="color:#006080;"&gt;'Banana'&lt;/span&gt;), &lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;        (&lt;span style="color:#006080;"&gt;'Cherry'&lt;/span&gt;)&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;    ) &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;New&lt;/span&gt;;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;The tables now look like this (parent first):&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_796FB1B9.png" target="_blank"&gt;&lt;img title="Original Data" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="Original Data" src="http://sqlblog.com/blogs/paul_white/image_thumb_3141F5DD.png" width="168" height="203" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can now add the required &lt;strong&gt;FOREIGN KEY&lt;/strong&gt; relationship:&lt;/p&gt;

&lt;div id="codeSnippetWrapper" style="overflow:auto;cursor:text;font-size:8pt;border-top:silver 1px solid;font-family:'Courier New', courier, monospace;border-right:silver 1px solid;border-bottom:silver 1px solid;padding-bottom:4px;direction:ltr;text-align:left;padding-top:4px;padding-left:4px;margin:20px 0px 10px;border-left:silver 1px solid;line-height:12pt;padding-right:4px;max-height:200px;width:97.5%;background-color:#f4f4f4;"&gt;
  &lt;div id="codeSnippet" style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;
    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;&lt;span style="color:#0000ff;"&gt;ALTER&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;TABLE&lt;/span&gt; dbo.Child&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;&lt;span style="color:#0000ff;"&gt;ADD&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;CONSTRAINT&lt;/span&gt; FK_Child_Parent&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;&lt;span style="color:#0000ff;"&gt;FOREIGN&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;KEY&lt;/span&gt; (parent_id)&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;&lt;span style="color:#0000ff;"&gt;REFERENCES&lt;/span&gt; dbo.Parent (parent_id);&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;Next, a very simple &lt;strong&gt;indexed view&lt;/strong&gt; that joins the two tables (the view could contain more complex features like aggregates):&lt;/font&gt;&lt;/p&gt;

&lt;div id="codeSnippetWrapper" style="overflow:auto;cursor:text;font-size:8pt;border-top:silver 1px solid;font-family:'Courier New', courier, monospace;border-right:silver 1px solid;border-bottom:silver 1px solid;padding-bottom:4px;direction:ltr;text-align:left;padding-top:4px;padding-left:4px;margin:20px 0px 10px;border-left:silver 1px solid;line-height:12pt;padding-right:4px;max-height:300px;width:97.5%;background-color:#f4f4f4;"&gt;
  &lt;div id="codeSnippet" style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;
    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;&lt;span style="color:#0000ff;"&gt;CREATE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;VIEW&lt;/span&gt; dbo.ParentsAndChildren&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;&lt;span style="color:#0000ff;"&gt;WITH&lt;/span&gt; SCHEMABINDING &lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;&lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; &lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;    p.parent_id, &lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;    p.&lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;, &lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;    c.child_id&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;&lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; dbo.Parent &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; p&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;&lt;span style="color:#0000ff;"&gt;JOIN&lt;/span&gt; dbo.Child &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; c &lt;span style="color:#0000ff;"&gt;ON&lt;/span&gt; &lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;    c.parent_id = p.parent_id;&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;&lt;span style="color:#0000ff;"&gt;GO&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;&lt;span style="color:#0000ff;"&gt;CREATE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;UNIQUE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;CLUSTERED&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;INDEX&lt;/span&gt; cuq &lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;&lt;span style="color:#0000ff;"&gt;ON&lt;/span&gt; dbo.ParentsAndChildren (child_id);&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;The final step is to use a MERGE statement to make some changes to the Parent table:&lt;/font&gt;&lt;/p&gt;

&lt;div id="codeSnippetWrapper" style="overflow:auto;cursor:text;font-size:8pt;border-top:silver 1px solid;font-family:'Courier New', courier, monospace;border-right:silver 1px solid;border-bottom:silver 1px solid;padding-bottom:4px;direction:ltr;text-align:left;padding-top:4px;padding-left:4px;margin:20px 0px 10px;border-left:silver 1px solid;line-height:12pt;padding-right:4px;max-height:400px;width:97.5%;background-color:#f4f4f4;"&gt;
  &lt;div id="codeSnippet" style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;
    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;&lt;span style="color:#0000ff;"&gt;DECLARE&lt;/span&gt; @ParentMerge &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;TABLE&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;(&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;    parent_id &lt;span style="color:#0000ff;"&gt;integer&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;PRIMARY&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;KEY&lt;/span&gt;, &lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;    &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;varchar&lt;/span&gt;(20) &lt;span style="color:#0000ff;"&gt;NOT&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;NULL&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;);&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;INSERT @ParentMerge&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;    (parent_id, &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;)&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;&lt;span style="color:#0000ff;"&gt;VALUES&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;    (1, &lt;span style="color:#006080;"&gt;'Kiwi Fruit'&lt;/span&gt;),&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;    (4, &lt;span style="color:#006080;"&gt;'Dragon Fruit'&lt;/span&gt;);&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;MERGE dbo.Parent &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; p&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;&lt;span style="color:#0000ff;"&gt;USING&lt;/span&gt; @ParentMerge &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; s &lt;span style="color:#0000ff;"&gt;ON&lt;/span&gt; &lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;    s.parent_id = p.parent_id&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;&lt;span style="color:#0000ff;"&gt;WHEN&lt;/span&gt; MATCHED &lt;span style="color:#0000ff;"&gt;THEN&lt;/span&gt; &lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;    &lt;span style="color:#0000ff;"&gt;UPDATE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SET&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt; = s.&lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;&lt;span style="color:#0000ff;"&gt;WHEN&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;NOT&lt;/span&gt; MATCHED &lt;span style="color:#0000ff;"&gt;THEN&lt;/span&gt; &lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;    INSERT (&lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;) &lt;span style="color:#0000ff;"&gt;VALUES&lt;/span&gt; (s.&lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;)&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;&lt;span style="color:#0000ff;"&gt;OUTPUT&lt;/span&gt; &lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;    $&lt;span style="color:#0000ff;"&gt;action&lt;/span&gt;, &lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;    inserted.parent_id, &lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;    deleted.&lt;span style="color:#0000ff;"&gt;value&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; old_value, &lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;    inserted.&lt;span style="color:#0000ff;"&gt;value&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; new_value;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;This MERGE performs two actions:&lt;/font&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;font size="3" face="Calibri"&gt;Updates the value column of parent row 1 from Apple to Kiwi Fruit&lt;/font&gt; &lt;/li&gt;

  &lt;li&gt;&lt;font size="3" face="Calibri"&gt;Adds a new parent row 4 for Dragon Fruit&lt;/font&gt; &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;The statement includes an &lt;a href="http://msdn.microsoft.com/en-us/library/ms177564.aspx" target="_blank"&gt;OUTPUT&lt;/a&gt; clause to show the changes it makes (this is not required for the repro):&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_3634B15D.png" target="_blank"&gt;&lt;img title="MERGE changes" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="MERGE changes" src="http://sqlblog.com/blogs/paul_white/image_thumb_5C2A61B3.png" width="306" height="93" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;This confirms that the changes have been made as we requested: parent row 1 has changed; and row 4 has been added. The changes are reflected in the base tables:&lt;/font&gt;&lt;/p&gt;

&lt;div id="codeSnippetWrapper" style="overflow:auto;cursor:text;font-size:8pt;border-top:silver 1px solid;font-family:'Courier New', courier, monospace;border-right:silver 1px solid;border-bottom:silver 1px solid;padding-bottom:4px;direction:ltr;text-align:left;padding-top:4px;padding-left:4px;margin:20px 0px 10px;border-left:silver 1px solid;line-height:12pt;padding-right:4px;max-height:200px;width:97.5%;background-color:#f4f4f4;"&gt;
  &lt;div id="codeSnippet" style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;
    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; * &lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; dbo.Parent &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; p;&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; * &lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; dbo.Child &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; c;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_5432BF51.png" target="_blank"&gt;&lt;img title="Updated Base Table Data" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="Updated Base Table Data" src="http://sqlblog.com/blogs/paul_white/image_thumb_6536ED34.png" width="187" height="224" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;As highlighted, row 1 has changed from &lt;em&gt;Apple&lt;/em&gt; to &lt;em&gt;Kiwi Fruit&lt;/em&gt; and row 4 has been added.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;We do &lt;em&gt;not&lt;/em&gt; expect to see row 4 in the indexed view because there are no child records for that row, and the indexed view uses an &lt;em&gt;inner&lt;/em&gt; join. Checking the indexed view using the NOEXPAND table hint (required in non-Enterprise SKUs to use indexes on a view):&lt;/font&gt;&lt;/p&gt;

&lt;div id="codeSnippetWrapper" style="overflow:auto;cursor:text;font-size:8pt;border-top:silver 1px solid;font-family:'Courier New', courier, monospace;border-right:silver 1px solid;border-bottom:silver 1px solid;padding-bottom:4px;direction:ltr;text-align:left;padding-top:4px;padding-left:4px;margin:20px 0px 10px;border-left:silver 1px solid;line-height:12pt;padding-right:4px;max-height:200px;width:97.5%;background-color:#f4f4f4;"&gt;
  &lt;div id="codeSnippet" style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;
    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; *&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;&lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; dbo.ParentsAndChildren &lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;&lt;span style="color:#0000ff;"&gt;WITH&lt;/span&gt; (NOEXPAND);&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_2ADB7753.png" target="_blank"&gt;&lt;img title="Incorrect indexed view data" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="Incorrect indexed view data" src="http://sqlblog.com/blogs/paul_white/image_thumb_22E3D4F1.png" width="217" height="111" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;&lt;strong&gt;The results are incorrect.&lt;/strong&gt; They show the old value of the data for parent row 1.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;Now we try using the &lt;a href="http://msdn.microsoft.com/en-us/library/ms181714.aspx" target="_blank"&gt;EXPAND VIEWS&lt;/a&gt; query hint to force SQL Server to access the base tables rather than reading view indexes:&lt;/font&gt;&lt;/p&gt;

&lt;div id="codeSnippetWrapper" style="overflow:auto;cursor:text;font-size:8pt;border-top:silver 1px solid;font-family:'Courier New', courier, monospace;border-right:silver 1px solid;border-bottom:silver 1px solid;padding-bottom:4px;direction:ltr;text-align:left;padding-top:4px;padding-left:4px;margin:20px 0px 10px;border-left:silver 1px solid;line-height:12pt;padding-right:4px;max-height:200px;width:97.5%;background-color:#f4f4f4;"&gt;
  &lt;div id="codeSnippet" style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;
    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; *&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;&lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; dbo.ParentsAndChildren&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;&lt;span style="color:#0000ff;"&gt;OPTION&lt;/span&gt; (EXPAND VIEWS);&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_48D98547.png" target="_blank"&gt;&lt;img title="Expand Views Hint" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="Expand Views Hint" src="http://sqlblog.com/blogs/paul_white/image_thumb_40E1E2E5.png" width="223" height="113" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;&lt;strong&gt;This query produces correct results&lt;/strong&gt;.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;On SQL Server Enterprise Edition, the optimizer chooses whether to access the indexed view or the base tables. For following query, without any hints, the optimizer chooses not to expand the view. It reads the view index and produces &lt;strong&gt;incorrect&lt;/strong&gt; results:&lt;/font&gt;&lt;/p&gt;

&lt;div id="codeSnippetWrapper" style="overflow:auto;cursor:text;font-size:8pt;border-top:silver 1px solid;font-family:'Courier New', courier, monospace;border-right:silver 1px solid;border-bottom:silver 1px solid;padding-bottom:4px;direction:ltr;text-align:left;padding-top:4px;padding-left:4px;margin:20px 0px 10px;border-left:silver 1px solid;line-height:12pt;padding-right:4px;max-height:200px;width:97.5%;background-color:#f4f4f4;"&gt;
  &lt;div id="codeSnippet" style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;
    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;&lt;span style="color:#008000;"&gt;-- Enterprise Edition ONLY&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; * &lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;&lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; dbo.ParentsAndChildren;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_14C4E5F4.png" target="_blank"&gt;&lt;img title="Indexed View Matching" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="Indexed View Matching" src="http://sqlblog.com/blogs/paul_white/image_thumb_0CCD4392.png" width="217" height="111" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;Perhaps adding a child row to match the new parent row 4 will somehow fix things up?&lt;/font&gt;&lt;/p&gt;

&lt;div id="codeSnippetWrapper" style="overflow:auto;cursor:text;font-size:8pt;border-top:silver 1px solid;font-family:'Courier New', courier, monospace;border-right:silver 1px solid;border-bottom:silver 1px solid;padding-bottom:4px;direction:ltr;text-align:left;padding-top:4px;padding-left:4px;margin:20px 0px 10px;border-left:silver 1px solid;line-height:12pt;padding-right:4px;max-height:200px;width:97.5%;background-color:#f4f4f4;"&gt;
  &lt;div id="codeSnippet" style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;
    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;INSERT dbo.Child (parent_id) &lt;span style="color:#0000ff;"&gt;VALUES&lt;/span&gt; (4);&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;&lt;span style="color:#0000ff;"&gt;GO&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; * &lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; dbo.ParentsAndChildren &lt;span style="color:#0000ff;"&gt;WITH&lt;/span&gt; (NOEXPAND);&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; * &lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; dbo.ParentsAndChildren &lt;span style="color:#0000ff;"&gt;OPTION&lt;/span&gt; (EXPAND VIEWS);&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_32C2F3E8.png" target="_blank"&gt;&lt;img title="After Insert" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="After Insert" src="http://sqlblog.com/blogs/paul_white/image_thumb_71B47483.png" width="239" height="248" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;No. The query plan that accesses the view index still returns an incorrect value for row 1. &lt;strong&gt;It seems MERGE has corrupted our indexed view&lt;/strong&gt;.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;&lt;/font&gt;&lt;/p&gt;

&lt;h3&gt;Analysis using DBCC CHECKTABLE&lt;/h3&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;Checking the view with &lt;a href="http://msdn.microsoft.com/en-us/library/ms174338.aspx" target="_blank"&gt;DBCC CHECKTABLE&lt;/a&gt; returns no errors:&lt;/font&gt;&lt;/p&gt;

&lt;div id="codeSnippetWrapper" style="overflow:auto;cursor:text;font-size:8pt;border-top:silver 1px solid;font-family:'Courier New', courier, monospace;border-right:silver 1px solid;border-bottom:silver 1px solid;padding-bottom:4px;direction:ltr;text-align:left;padding-top:4px;padding-left:4px;margin:20px 0px 10px;border-left:silver 1px solid;line-height:12pt;padding-right:4px;max-height:200px;width:97.5%;background-color:#f4f4f4;"&gt;
  &lt;div id="codeSnippet" style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;
    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;&lt;span style="color:#0000ff;"&gt;DBCC&lt;/span&gt; CHECKTABLE (ParentsAndChildren);&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_4935926F.png" target="_blank"&gt;&lt;img title="DBCC output 1" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="DBCC output 1" src="http://sqlblog.com/blogs/paul_white/image_thumb_6F2B42C5.png" width="644" height="83" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;Unless we use the &lt;strong&gt;EXTENDED_LOGICAL_CHECKS&lt;/strong&gt; option:&lt;/font&gt;&lt;/p&gt;

&lt;div id="codeSnippetWrapper" style="overflow:auto;cursor:text;font-size:8pt;border-top:silver 1px solid;font-family:'Courier New', courier, monospace;border-right:silver 1px solid;border-bottom:silver 1px solid;padding-bottom:4px;direction:ltr;text-align:left;padding-top:4px;padding-left:4px;margin:20px 0px 10px;border-left:silver 1px solid;line-height:12pt;padding-right:4px;max-height:200px;width:97.5%;background-color:#f4f4f4;"&gt;
  &lt;div id="codeSnippet" style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;
    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;&lt;span style="color:#0000ff;"&gt;DBCC&lt;/span&gt; CHECKTABLE (ParentsAndChildren) &lt;span style="color:#0000ff;"&gt;WITH&lt;/span&gt; EXTENDED_LOGICAL_CHECKS;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_7837CE46.png" target="_blank"&gt;&lt;img title="DBCC output 2" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="DBCC output 2" src="http://sqlblog.com/blogs/paul_white/image_thumb_6B5D7828.png" width="644" height="217" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;The damage is repairable:&lt;/font&gt;&lt;/p&gt;

&lt;div id="codeSnippetWrapper" style="overflow:auto;cursor:text;font-size:8pt;border-top:silver 1px solid;font-family:'Courier New', courier, monospace;border-right:silver 1px solid;border-bottom:silver 1px solid;padding-bottom:4px;direction:ltr;text-align:left;padding-top:4px;padding-left:4px;margin:20px 0px 10px;border-left:silver 1px solid;line-height:12pt;padding-right:4px;max-height:200px;width:97.5%;background-color:#f4f4f4;"&gt;
  &lt;div id="codeSnippet" style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;
    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;&lt;span style="color:#0000ff;"&gt;ALTER&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;DATABASE&lt;/span&gt; Sandpit &lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;&lt;span style="color:#0000ff;"&gt;SET&lt;/span&gt; SINGLE_USER &lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;&lt;span style="color:#0000ff;"&gt;WITH&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;ROLLBACK&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;IMMEDIATE&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;&lt;span style="color:#0000ff;"&gt;GO&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;&lt;span style="color:#0000ff;"&gt;DBCC&lt;/span&gt; CHECKTABLE (ParentsAndChildren, REPAIR_REBUILD) &lt;span style="color:#0000ff;"&gt;WITH&lt;/span&gt; EXTENDED_LOGICAL_CHECKS;&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;&lt;span style="color:#0000ff;"&gt;GO&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;&lt;span style="color:#0000ff;"&gt;DBCC&lt;/span&gt; CHECKTABLE (ParentsAndChildren) &lt;span style="color:#0000ff;"&gt;WITH&lt;/span&gt; EXTENDED_LOGICAL_CHECKS;&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;&lt;span style="color:#0000ff;"&gt;GO&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;&lt;span style="color:#0000ff;"&gt;ALTER&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;DATABASE&lt;/span&gt; Sandpit &lt;span style="color:#0000ff;"&gt;SET&lt;/span&gt; MULTI_USER;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_191B1B21.png" target="_blank"&gt;&lt;img title="DBCC repair" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="DBCC repair" src="http://sqlblog.com/blogs/paul_white/image_thumb_3DCC3298.png" width="644" height="277" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;You probably do not want to set your database to SINGLE_USER mode and run a DBCC repair after every MERGE statement, however. We could also rebuild the indexed view’s clustered index manually, of course.&lt;/font&gt;&lt;/p&gt;

&lt;h2&gt;Cause&lt;/h2&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;For the MERGE statement above, the query optimizer builds a plan that &lt;strong&gt;does not update the indexed view&lt;/strong&gt; (click to enlarge):&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_072E6187.png" target="_blank"&gt;&lt;img title="Incorrect Update Plan" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="Incorrect Update Plan" src="http://sqlblog.com/blogs/paul_white/image_thumb_6A64C6A4.png" width="660" height="103" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;In a version of SQL Server with the fix applied, the same MERGE statement produces a plan that does maintain the indexed view:&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_73715225.png" target="_blank"&gt;&lt;img title="Correct Update Plan" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="Correct Update Plan" src="http://sqlblog.com/blogs/paul_white/image_thumb_049509FC.png" width="644" height="101" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;The plan operators used to keep the view index in step with the base tables are highlighted. Without these operators, the changes to the base table are not correctly written to any indexes defined on the view. The &lt;strong&gt;root cause&lt;/strong&gt; is related to the same simplification that allows the optimizer to remove the reference to the Parent table in this query:&lt;/font&gt;&lt;/p&gt;

&lt;div id="codeSnippetWrapper" style="overflow:auto;cursor:text;font-size:8pt;border-top:silver 1px solid;font-family:'Courier New', courier, monospace;border-right:silver 1px solid;border-bottom:silver 1px solid;padding-bottom:4px;direction:ltr;text-align:left;padding-top:4px;padding-left:4px;margin:20px 0px 10px;border-left:silver 1px solid;line-height:12pt;padding-right:4px;max-height:200px;width:97.5%;background-color:#f4f4f4;"&gt;
  &lt;div id="codeSnippet" style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;
    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; &lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;    COUNT_BIG(*)&lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;&lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; dbo.Parent &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; p &lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:#f4f4f4;"&gt;&lt;span style="color:#0000ff;"&gt;JOIN&lt;/span&gt; dbo.Child &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; c &lt;span style="color:#0000ff;"&gt;ON&lt;/span&gt; &lt;/pre&gt;


    &lt;pre style="border-top-style:none;overflow:visible;font-size:8pt;border-left-style:none;font-family:'Courier New', courier, monospace;border-bottom-style:none;color:black;padding-bottom:0px;direction:ltr;text-align:left;padding-top:0px;border-right-style:none;padding-left:0px;margin:0em;line-height:12pt;padding-right:0px;width:100%;background-color:white;"&gt;    c.parent_id = p.parent_id;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_0DA1957D.png" target="_blank"&gt;&lt;img title="Simplification Example Plan" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="Simplification Example Plan" src="http://sqlblog.com/blogs/paul_white/image_thumb_0C5CFC9E.png" width="314" height="87" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;The FOREIGN KEY relationship and NOT NULL constraints on the referencing column together mean that the join to Parent cannot affect the result of the query, so the join &lt;a href="http://msmvps.com/blogs/robfarley/archive/2008/11/09/join-simplification-in-sql-server.aspx" target="_blank"&gt;is simplified away&lt;/a&gt;. In SQL Server 2012, we can see when this simplification is performed because the following message appears when undocumented trace flags 8619 and 3604 are enabled during compilation:&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_2009E632.png" target="_blank"&gt;&lt;img title="Trace Flag 8619 output" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="Trace Flag 8619 output" src="http://sqlblog.com/blogs/paul_white/image_thumb_2A5B0A92.png" width="457" height="37" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;The same message is emitted when a MERGE statement contains a WHEN MATCHED THEN UPDATE clause and either a WHEN NOT MATCHED THEN INSERT or WHEN MATCHED … THEN DELETE clause. These conditions combine such that the optimizer incorrectly concludes that a table reference can be removed, when in fact it is needed later on when the update side of the plan is built.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;Other details of the query and database can affect whether the simplification can be misapplied. For example, if the FOREIGN KEY constraint contains an ON DELETE CASCADE clause, and the MERGE contains a DELETE clause, the simplification is not performed, the TF 8619 message does not appear, and the bug does not manifest.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;The key to determining whether a particular query is vulnerable to this bug (TF 8619 aside) is to check whether the query plan includes operators to maintain the indexed view. At a minimum, you should see a update operator for the view:&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_22636830.png" target="_blank"&gt;&lt;img title="View Update Operator" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="View Update Operator" src="http://sqlblog.com/blogs/paul_white/image_thumb_48591886.png" width="183" height="107" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;SQL Sentry &lt;a href="http://www.sqlsentry.net/plan-explorer/sql-server-query-view.asp" target="_blank"&gt;Plan Explorer&lt;/a&gt; identifies the operator as applying to a view explicitly, in SSMS you need to click on the graphical operator and inspect the Properties window.&lt;/font&gt;&lt;/p&gt;

&lt;h2&gt;Summary&lt;/h2&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;The updated conditions for incorrect results are:&lt;/font&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;font size="3" face="Calibri"&gt;An &lt;strong&gt;indexed view&lt;/strong&gt; that joins tables&lt;/font&gt; &lt;/li&gt;

  &lt;li&gt;&lt;font size="3" face="Calibri"&gt;Two of the tables have a single-column &lt;strong&gt;FOREIGN KEY constraint&lt;/strong&gt;&lt;/font&gt; &lt;/li&gt;

  &lt;li&gt;&lt;font size="3" face="Calibri"&gt;A &lt;strong&gt;MERGE&lt;/strong&gt; statement contains an &lt;strong&gt;UPDATE&lt;/strong&gt; action that affects one of the tables&lt;/font&gt; &lt;/li&gt;

  &lt;li&gt;&lt;font size="3" face="Calibri"&gt;The &lt;strong&gt;MERGE&lt;/strong&gt; statement also contains an &lt;strong&gt;INSERT or DELETE&lt;/strong&gt; action (or both)&lt;/font&gt; &lt;/li&gt;

  &lt;li&gt;&lt;font size="3" face="Calibri"&gt;The optimizer applies a &lt;strong&gt;simplification&lt;/strong&gt; that removes a table reference based on the FK relationship and other metadata&lt;/font&gt; &lt;/li&gt;

  &lt;li&gt;&lt;font size="3" face="Calibri"&gt;As a result, the MERGE execution plan does not contain the operators necessary to correctly maintain the indexed view&lt;/font&gt; &lt;/li&gt;

  &lt;li&gt;&lt;font size="3" face="Calibri"&gt;A subsequent query plan accesses an index on the view, either explicitly or via &lt;strong&gt;indexed-view matching&lt;/strong&gt; (Enterprise Edition)&lt;/font&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;&lt;em&gt;Note:&lt;/em&gt;&lt;/font&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;font size="3" face="Calibri"&gt;The simplification is not applied in &lt;em&gt;tempdb&lt;/em&gt;&lt;/font&gt; &lt;/li&gt;

  &lt;li&gt;&lt;font size="3" face="Calibri"&gt;The simplification is not applied to multi-column foreign key constraints&lt;/font&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;Under these conditions, &lt;strong&gt;the indexes on the view do not reflect the state of the base tables and incorrect results are returned&lt;/strong&gt;. Once the hot fix is applied, the optimizer does not misapply the simplification so the correct indexed view maintenance features are built into execution plans.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;&lt;strong&gt;Update:&lt;/strong&gt; I am adding this based on Ian Yates’ great question in the comments: my expectation is that &lt;strong&gt;applying this hotfix will not remove any existing indexed view corruption&lt;/strong&gt;. You would need to test the hotfix as usual, apply it, and then either rebuild all affected indexed views manually, or run DBCC CHECKDB with the EXTENDED_LOGICAL_CHECKS option (which could take a long time).&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;© 2013 Paul White – All Rights Reserved&lt;/font&gt;&lt;/p&gt;

&lt;p align="left"&gt;&lt;a title="SQL Intersection" href="http://www.sqlintersection.com/" target="_blank"&gt;&lt;img title="Ill_Be_There4" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="Ill_Be_There4" src="http://sqlblog.com/blogs/paul_white/Ill_Be_There4_0D1F26E1.jpg" width="140" height="110" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="3" face="Calibri"&gt;Twitter: &lt;a href="http://twitter.com/SQL_Kiwi"&gt;@SQL_Kiwi&lt;/a&gt; 

    &lt;br /&gt;Email: &lt;a href="mailto:SQLKiwi@gmail.com"&gt;SQLKiwi@gmail.com&lt;/a&gt;&lt;/font&gt;&lt;/p&gt;</description></item><item><title>MERGE Bug with Filtered Indexes</title><link>http://sqlblog.com/blogs/paul_white/archive/2012/12/09/merge-bug-with-filtered-indexes.aspx</link><pubDate>Sun, 09 Dec 2012 17:54:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:46572</guid><dc:creator>Paul White</dc:creator><description>&lt;p align="left"&gt;A MERGE statement can fail, and incorrectly report a unique key violation when:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;div align="left"&gt;The target table uses a unique filtered index; and&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="left"&gt;No key column of the filtered index is updated; and&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="left"&gt;A column from the filtering condition is updated; and&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="left"&gt;Transient key violations are possible&lt;/div&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;h3 align="left"&gt;Example Tables&lt;/h3&gt;  &lt;p align="left"&gt;Say we have two tables, one that is the target of a MERGE statement, and another that contains updates to be applied to the target.&amp;#160; The target table contains three columns, an integer primary key, a single character alternate key, and a status code column.&amp;#160; A filtered unique index exists on the alternate key, but is only enforced where the status code is ‘a’:&lt;/p&gt;  &lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:'Courier New', courier, monospace;direction:ltr;max-height:300px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;CREATE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;TABLE&lt;/span&gt; #Target &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;(&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    pk          &lt;span style="color:#0000ff;"&gt;integer&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;NOT&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;NULL&lt;/span&gt;, &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    ak          &lt;span style="color:#0000ff;"&gt;character&lt;/span&gt;(1) &lt;span style="color:#0000ff;"&gt;NOT&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;NULL&lt;/span&gt;,&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    status_code &lt;span style="color:#0000ff;"&gt;character&lt;/span&gt;(1) &lt;span style="color:#0000ff;"&gt;NOT&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;NULL&lt;/span&gt;,&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;PRIMARY&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;KEY&lt;/span&gt; (pk)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;CREATE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;UNIQUE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;INDEX&lt;/span&gt; uq1&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;ON&lt;/span&gt; #Target (ak)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;INCLUDE&lt;/span&gt; (status_code)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;WHERE&lt;/span&gt; status_code = &lt;span style="color:#006080;"&gt;'a'&lt;/span&gt;;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p align="left"&gt;The changes table contains just an integer primary key (to identify the target row to change) and the new status code:&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:'Courier New', courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;CREATE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;TABLE&lt;/span&gt; #Changes&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;(&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    pk          &lt;span style="color:#0000ff;"&gt;integer&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;NOT&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;NULL&lt;/span&gt;,&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    status_code &lt;span style="color:#0000ff;"&gt;character&lt;/span&gt;(1) &lt;span style="color:#0000ff;"&gt;NOT&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;NULL&lt;/span&gt;,&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;PRIMARY&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;KEY&lt;/span&gt; (pk)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;);&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;h3 align="left"&gt;Sample Data&lt;/h3&gt;

&lt;p align="left"&gt;The sample data for the example is:&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:'Courier New', courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;INSERT #Target &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    (pk, ak, status_code)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;VALUES&lt;/span&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    (1, &lt;span style="color:#006080;"&gt;'A'&lt;/span&gt;, &lt;span style="color:#006080;"&gt;'a'&lt;/span&gt;),&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    (2, &lt;span style="color:#006080;"&gt;'B'&lt;/span&gt;, &lt;span style="color:#006080;"&gt;'a'&lt;/span&gt;),&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    (3, &lt;span style="color:#006080;"&gt;'C'&lt;/span&gt;, &lt;span style="color:#006080;"&gt;'a'&lt;/span&gt;),&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    (4, &lt;span style="color:#006080;"&gt;'A'&lt;/span&gt;, &lt;span style="color:#006080;"&gt;'d'&lt;/span&gt;);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;INSERT #Changes&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    (pk, status_code)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;VALUES&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    (1, &lt;span style="color:#006080;"&gt;'d'&lt;/span&gt;),&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    (4, &lt;span style="color:#006080;"&gt;'a'&lt;/span&gt;);&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;font face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;b&gt;Target&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Changes&lt;/b&gt; 

    &lt;br /&gt;╔════╦════╦═════════════╗&amp;#160;&amp;#160;&amp;#160; ╔════╦═════════════╗ 

    &lt;br /&gt;║ pk ║ ak ║ status_code ║&amp;#160;&amp;#160;&amp;#160; ║ pk ║ status_code ║ 

    &lt;br /&gt;╠════╬════╬═════════════╣&amp;#160;&amp;#160;&amp;#160; ╠════╬═════════════╣ 

    &lt;br /&gt;║&amp;#160; 1 ║ A&amp;#160; ║ a&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ║&amp;#160;&amp;#160;&amp;#160; ║&amp;#160; 1 ║ d&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ║ 

    &lt;br /&gt;║&amp;#160; 2 ║ B&amp;#160; ║ a&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ║&amp;#160;&amp;#160;&amp;#160; ║&amp;#160; 4 ║ a&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ║ 

    &lt;br /&gt;║&amp;#160; 3 ║ C&amp;#160; ║ a&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ║&amp;#160;&amp;#160;&amp;#160; ╚════╩═════════════╝ 

    &lt;br /&gt;║&amp;#160; 4 ║ A&amp;#160; ║ d&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ║ 

    &lt;br /&gt;╚════╩════╩═════════════╝&lt;/font&gt; 

  &lt;br /&gt;&lt;/p&gt;

&lt;p align="left"&gt;The target table’s alternate key (ak) column is unique, for rows where status_code = ‘a’.&amp;#160; Applying the changes to the target will change row 1 from status ‘a’ to status ‘d’, and row 4 from status ‘d’ to status ‘a’.&amp;#160; The result of applying all the changes will still satisfy the filtered unique index, because the ‘A’ in row 1 will be deleted from the index and the ‘A’ in row 4 will be added.&lt;/p&gt;

&lt;h3 align="left"&gt;Merge Test One&lt;/h3&gt;

&lt;p align="left"&gt;Let’s now execute a MERGE statement to apply the changes:&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:'Courier New', courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;MERGE #Target &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; t&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;USING&lt;/span&gt; #Changes &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; c &lt;span style="color:#0000ff;"&gt;ON&lt;/span&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    c.pk = t.pk&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;WHEN&lt;/span&gt; MATCHED &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;AND&lt;/span&gt; c.status_code &amp;lt;&amp;gt; t.status_code &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;THEN&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;UPDATE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SET&lt;/span&gt; status_code = c.status_code;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p align="left"&gt;The MERGE changes the two target rows as expected.&amp;#160; The updated target table now contains:&lt;/p&gt;

&lt;p&gt;&lt;font face="Courier New"&gt;╔════╦════╦═════════════╗ 
    &lt;br /&gt;║ pk ║ ak ║ status_code ║ 

    &lt;br /&gt;╠════╬════╬═════════════╣ 

    &lt;br /&gt;║&amp;#160; 1 ║ A&amp;#160; ║ &lt;b&gt;&lt;font color="#ff0000"&gt;d&lt;/font&gt;&lt;/b&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ║ &amp;lt;—changed from ‘a’ 

    &lt;br /&gt;║&amp;#160; 2 ║ B&amp;#160; ║ a&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ║ 

    &lt;br /&gt;║&amp;#160; 3 ║ C&amp;#160; ║ a&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ║ 

    &lt;br /&gt;║&amp;#160; 4 ║ A&amp;#160; ║ &lt;b&gt;&lt;font color="#ff0000"&gt;a&lt;/font&gt;&lt;/b&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ║ &amp;lt;—changed from ‘d’ 

    &lt;br /&gt;╚════╩════╩═════════════╝&lt;/font&gt;&lt;/p&gt;

&lt;h3 align="left"&gt;Merge Test Two&lt;/h3&gt;

&lt;p align="left"&gt;Now let’s repopulate the changes table to reverse the updates we just performed:&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:'Courier New', courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;TRUNCATE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;TABLE&lt;/span&gt; #Changes;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;INSERT #Changes&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    (pk, status_code)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;VALUES&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    (1, &lt;span style="color:#006080;"&gt;'a'&lt;/span&gt;),&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    (4, &lt;span style="color:#006080;"&gt;'d'&lt;/span&gt;);&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p align="left"&gt;This will change row 1 back to status ‘a’ and row 4 back to status ‘d’.&amp;#160; As a reminder, the current state of the tables is:&lt;/p&gt;

&lt;p&gt;&lt;font face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;b&gt;Target&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Changes&lt;/b&gt; 

    &lt;br /&gt;╔════╦════╦═════════════╗&amp;#160;&amp;#160;&amp;#160; ╔════╦═════════════╗ 

    &lt;br /&gt;║ pk ║ ak ║ status_code ║&amp;#160;&amp;#160;&amp;#160; ║ pk ║ status_code ║ 

    &lt;br /&gt;╠════╬════╬═════════════╣&amp;#160;&amp;#160;&amp;#160; ╠════╬═════════════╣ 

    &lt;br /&gt;║&amp;#160; 1 ║ A&amp;#160; ║ d&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ║&amp;#160;&amp;#160;&amp;#160; ║&amp;#160; 1 ║ a&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ║ 

    &lt;br /&gt;║&amp;#160; 2 ║ B&amp;#160; ║ a&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ║&amp;#160;&amp;#160;&amp;#160; ║&amp;#160; 4 ║ d&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ║ 

    &lt;br /&gt;║&amp;#160; 3 ║ C&amp;#160; ║ a&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ║&amp;#160;&amp;#160;&amp;#160; ╚════╩═════════════╝ 

    &lt;br /&gt;║&amp;#160; 4 ║ A&amp;#160; ║ a&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ║ 

    &lt;br /&gt;╚════╩════╩═════════════╝&lt;/font&gt; 

  &lt;br /&gt;&lt;/p&gt;

&lt;p align="left"&gt;We execute the same MERGE statement:&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:'Courier New', courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;MERGE #Target &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; t&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;USING&lt;/span&gt; #Changes &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; c &lt;span style="color:#0000ff;"&gt;ON&lt;/span&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    c.pk = t.pk&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;WHEN&lt;/span&gt; MATCHED &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;AND&lt;/span&gt; c.status_code &amp;lt;&amp;gt; t.status_code &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;THEN&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;UPDATE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SET&lt;/span&gt; status_code = c.status_code;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p align="left"&gt;However this time we receive the following message:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;font face="Courier New"&gt;&lt;font color="#ff0000"&gt;Msg 2601, Level 14, State 1, Line 1 
        &lt;br /&gt;Cannot insert duplicate key row in object 'dbo.#Target' with unique index 'uq1'. The duplicate key value is (A). 

        &lt;br /&gt;&lt;/font&gt;The statement has been terminated.&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;Applying the changes using UPDATE&lt;/h3&gt;

&lt;p align="left"&gt;Let’s now rewrite the MERGE to use UPDATE instead:&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:'Courier New', courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;UPDATE&lt;/span&gt; t&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;SET&lt;/span&gt; status_code = c.status_code&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; #Target &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; t&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;JOIN&lt;/span&gt; #Changes &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; c &lt;span style="color:#0000ff;"&gt;ON&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    t.pk = c.pk&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;WHERE&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    c.status_code &amp;lt;&amp;gt; t.status_code;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;This query succeeds where the MERGE failed.&amp;#160; The two rows are updated as expected:&lt;/p&gt;

&lt;p&gt;&lt;font face="Courier New"&gt;╔════╦════╦═════════════╗ 
    &lt;br /&gt;║ pk ║ ak ║ status_code ║ 

    &lt;br /&gt;╠════╬════╬═════════════╣ 

    &lt;br /&gt;║&amp;#160; 1 ║ A&amp;#160; ║ &lt;b&gt;&lt;font color="#ff0000"&gt;a&lt;/font&gt;&lt;/b&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ║ &amp;lt;—changed back to ‘a’ 

    &lt;br /&gt;║&amp;#160; 2 ║ B&amp;#160; ║ a&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ║ 

    &lt;br /&gt;║&amp;#160; 3 ║ C&amp;#160; ║ a&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ║ 

    &lt;br /&gt;║&amp;#160; 4 ║ A&amp;#160; ║ &lt;b&gt;&lt;font color="#ff0000"&gt;d&lt;/font&gt;&lt;/b&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ║ &amp;lt;—changed back to ‘d’ 

    &lt;br /&gt;╚════╩════╩═════════════╝&lt;/font&gt;&lt;/p&gt;

&lt;h3&gt;What went wrong with the MERGE?&lt;/h3&gt;

&lt;p align="left"&gt;In this test, the MERGE query execution happens to apply the changes in the order of the ‘pk’ column.&lt;/p&gt;

&lt;p align="left"&gt;&lt;b&gt;In test one, this was not a problem&lt;/b&gt;: row 1 is removed from the unique filtered index by changing status_code from ‘a’ to ‘d’ before row 4 is added.&amp;#160; At no point does the table contain two rows where ak = ‘A’ and status_code = ‘a’.&lt;/p&gt;

&lt;p align="left"&gt;&lt;b&gt;In test two, however&lt;/b&gt;, the first change was to change row 1 from status ‘d’ to status ‘a’.&amp;#160; This change means there would be two rows in the filtered unique index where ak = ‘A’ (both row 1 and row 4 meet the index filtering criteria ‘status_code = a’).&lt;/p&gt;

&lt;p align="left"&gt;The storage engine does not allow the query processor to violate a unique key (unless IGNORE_DUP_KEY is ON, but that is a different story, and doesn’t apply to MERGE in any case).&amp;#160; This strict rule applies regardless of the fact that if &lt;b&gt;all&lt;/b&gt; changes were applied, there would be no unique key violation (row 4 would eventually be changed from ‘a’ to ‘d’, removing it from the filtered unique index, and resolving the key violation).&lt;/p&gt;

&lt;h3 align="left"&gt;Why it went wrong&lt;/h3&gt;

&lt;p align="left"&gt;The query optimizer usually detects when this sort of &lt;b&gt;temporary uniqueness violation&lt;/b&gt; could occur, and builds a plan that avoids the issue.&amp;#160; I wrote about this a couple of years ago in my post &lt;a href="http://bit.ly/SneakyReads" target="_blank"&gt;Beware Sneaky Reads with Unique Indexes&lt;/a&gt; (you can read more about the details on pages 495-497 of &lt;a href="http://www.microsoft.com/learning/en/us/book.aspx?id=12967" target="_blank"&gt;Microsoft SQL Server 2008 Internals&lt;/a&gt; or in Craig Freedman’s &lt;a href="http://blogs.msdn.com/b/craigfr/archive/2007/09/06/maintaining-unique-indexes.aspx" target="_blank"&gt;blog post&lt;/a&gt; on maintaining unique indexes).&amp;#160; To summarize though, the optimizer introduces &lt;b&gt;Split, Filter, Sort, and Collapse&lt;/b&gt; operators into the query plan to:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;div align="left"&gt;&lt;b&gt;Split&lt;/b&gt; each row update into delete followed by an inserts&lt;/div&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;div align="left"&gt;&lt;b&gt;Filter&lt;/b&gt; out rows that would not change the index (due to the filter on the index, or a &lt;a href="http://bit.ly/NonUpdatingUpdates" target="_blank"&gt;non-updating update&lt;/a&gt;)&lt;/div&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;div align="left"&gt;&lt;b&gt;Sort&lt;/b&gt; the resulting stream by index key, with deletes before inserts&lt;/div&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;div align="left"&gt;&lt;b&gt;Collapse&lt;/b&gt; delete/insert pairs on the same index key back into an update&lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p align="left"&gt;The effect of all this is that &lt;b&gt;only net changes are applied&lt;/b&gt; to an index (as one or more insert, update, and/or delete operations).&amp;#160; In this case, the net effect is a single update of the filtered unique index: changing the row for ak = ‘A’ from pk = 4 to pk = 1.&amp;#160; In case that is less than 100% clear, let’s look at the operation in test two again:&lt;/p&gt;

&lt;p&gt;&lt;font face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;b&gt;Target&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Changes&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Result&lt;/b&gt; 

    &lt;br /&gt;╔════╦════╦═════════════╗&amp;#160;&amp;#160;&amp;#160; ╔════╦═════════════╗&amp;#160;&amp;#160;&amp;#160; ╔════╦════╦═════════════╗ 

    &lt;br /&gt;║ pk ║ ak ║ status_code ║&amp;#160;&amp;#160;&amp;#160; ║ pk ║ status_code ║&amp;#160;&amp;#160;&amp;#160; ║ pk ║ ak ║ status_code ║ 

    &lt;br /&gt;╠════╬════╬═════════════╣&amp;#160;&amp;#160;&amp;#160; ╠════╬═════════════╣&amp;#160;&amp;#160;&amp;#160; ╠════╬════╬═════════════╣ 

    &lt;br /&gt;║&amp;#160; 1 ║ A&amp;#160; ║ d&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ║&amp;#160;&amp;#160;&amp;#160; ║&amp;#160; 1 ║ d&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ║&amp;#160;&amp;#160;&amp;#160; ║&amp;#160; 1 ║ A&amp;#160; ║ a&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ║ 

    &lt;br /&gt;║&amp;#160; 2 ║ B&amp;#160; ║ a&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ║&amp;#160;&amp;#160;&amp;#160; ║&amp;#160; 4 ║ a&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ║&amp;#160;&amp;#160;&amp;#160; ║&amp;#160; 2 ║ B&amp;#160; ║ a&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ║ 

    &lt;br /&gt;║&amp;#160; 3 ║ C&amp;#160; ║ a&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ║&amp;#160;&amp;#160;&amp;#160; ╚════╩═════════════╝&amp;#160;&amp;#160;&amp;#160; ║&amp;#160; 3 ║ C&amp;#160; ║ a&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ║ 

    &lt;br /&gt;║&amp;#160; 4 ║ A&amp;#160; ║ a&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ║&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ║&amp;#160; 4 ║ A&amp;#160; ║ d&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ║ 

    &lt;br /&gt;╚════╩════╩═════════════╝&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ╚════╩════╩═════════════╝&lt;/font&gt; 

  &lt;br /&gt;&lt;/p&gt;

&lt;p align="left"&gt;From the &lt;b&gt;filtered index’s point of view&lt;/b&gt; (filtered for status_code = ‘a’ and shown in nonclustered index key order) the overall effect of the query is:&lt;/p&gt;

&lt;p&gt;&lt;font face="Courier New"&gt;&lt;b&gt;&amp;#160; Before&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; After 
      &lt;br /&gt;&lt;/b&gt;╔════╦════╗&amp;#160;&amp;#160;&amp;#160; ╔════╦════╗ 

    &lt;br /&gt;║ pk ║ ak ║&amp;#160;&amp;#160;&amp;#160; ║ pk ║ ak ║ 

    &lt;br /&gt;╠════╬════╣&amp;#160;&amp;#160;&amp;#160; ╠════╬════╣ 

    &lt;br /&gt;║&amp;#160; &lt;font color="#ff0000"&gt;&lt;b&gt;4&lt;/b&gt;&lt;/font&gt; ║ A&amp;#160; ║&amp;#160;&amp;#160;&amp;#160; ║&amp;#160; &lt;b&gt;&lt;font color="#ff0000"&gt;1&lt;/font&gt;&lt;/b&gt; ║ A&amp;#160; ║ 

    &lt;br /&gt;║&amp;#160; 2 ║ B&amp;#160; ║&amp;#160;&amp;#160;&amp;#160; ║&amp;#160; 2 ║ B&amp;#160; ║ 

    &lt;br /&gt;║&amp;#160; 3 ║ C&amp;#160; ║&amp;#160;&amp;#160;&amp;#160; ║&amp;#160; 3 ║ C&amp;#160; ║ 

    &lt;br /&gt;╚════╩════╝&amp;#160;&amp;#160;&amp;#160; ╚════╩════╝&lt;/font&gt; 

  &lt;br /&gt;&lt;/p&gt;

&lt;p align="left"&gt;The &lt;b&gt;single net change&lt;/b&gt; there is a change of pk from 4 to 1 for the nonclustered index entry ak = ‘A’.&amp;#160; This is the magic performed by the split, sort, and collapse.&amp;#160; Notice in particular how the original changes to the index key (on the ‘ak’ column) have been transformed into an update of a non-key column (pk is included in the nonclustered index).&amp;#160; By not updating any nonclustered index keys, we are &lt;b&gt;guaranteed to avoid transient key violations&lt;/b&gt;.&lt;/p&gt;

&lt;h3 align="left"&gt;The Execution Plans&lt;/h3&gt;

&lt;p align="left"&gt;The estimated MERGE execution plan that produces the &lt;b&gt;incorrect key-violation error&lt;/b&gt; looks like this (click to enlarge in a new window):&lt;/p&gt;

&lt;p align="left"&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_0C120630.png" target="_blank"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="MERGE plan" border="0" alt="MERGE plan" src="http://sqlblog.com/blogs/paul_white/image_thumb_7BB68E76.png" width="660" height="142" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p align="left"&gt;The successful UPDATE execution plan is (click to enlarge in a new window):&lt;/p&gt;

&lt;p align="left"&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_58A61D06.png" target="_blank"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="UPDATE execution plan" border="0" alt="UPDATE execution plan" src="http://sqlblog.com/blogs/paul_white/image_thumb_15E6D1CE.png" width="660" height="111" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p align="left"&gt;The MERGE execution plan is a &lt;b&gt;narrow&lt;/b&gt; (per-row) update.&amp;#160; The single Clustered Index Merge operator maintains both the clustered index and the filtered nonclustered index.&amp;#160; The UPDATE plan is a &lt;b&gt;wide&lt;/b&gt; (per-index) update.&amp;#160; The clustered index is maintained first, then the Split, Filter, Sort, Collapse sequence is applied before the nonclustered index is separately maintained.&lt;/p&gt;

&lt;p align="left"&gt;&lt;b&gt;There is always a wide update plan&lt;/b&gt; for any query that modifies the database. The narrow form is a performance optimization where the number of rows is expected to be relatively small, and is not available for all operations.&amp;#160; One of the operations that &lt;b&gt;should disallow a narrow plan&lt;/b&gt; is maintaining a unique index where intermediate key violations could occur.&lt;/p&gt;

&lt;h3 align="left"&gt;Workarounds&lt;/h3&gt;

&lt;p align="left"&gt;The MERGE can be made to work (producing a wide update plan with split, sort, and collapse) by:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;div align="left"&gt;Adding all columns referenced in the filtered index’s WHERE clause to the index key (INCLUDE is not sufficient); or&lt;/div&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;div align="left"&gt;Executing the query with trace flag 8790 set e.g. OPTION (QUERYTRACEON 8790).&lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p align="left"&gt;Undocumented trace flag 8790 forces a wide update plan for any data-changing query (remember that a wide update plan is always possible).&amp;#160; Either change will produce a successfully-executing wide update plan for the MERGE that failed previously.&lt;/p&gt;

&lt;h3 align="left"&gt;Conclusion&lt;/h3&gt;

&lt;p align="left"&gt;The optimizer fails to spot the possibility of transient unique key violations with MERGE under the conditions listed at the start of this post.&amp;#160; It incorrectly chooses a narrow plan for the MERGE, which cannot provide the protection of a split/sort/collapse sequence for the nonclustered index maintenance.&lt;/p&gt;

&lt;p align="left"&gt;The MERGE plan may fail at execution time depending on the order in which rows are processed, and the distribution of data in the database.&amp;#160; Worse, a previously solid MERGE query may &lt;b&gt;suddenly start to fail unpredictably&lt;/b&gt; if a filtered unique index is added to the merge target table at any point.&lt;/p&gt;

&lt;p align="left"&gt;&lt;a href="https://connect.microsoft.com/SQLServer/feedback/details/773895/merge-incorrectly-reports-unique-key-violations" target="_blank"&gt;Connect bug filed here&lt;/a&gt;&lt;/p&gt;

&lt;p align="left"&gt;&lt;i&gt;Bug reproduced on the following SQL Server versions (all x64 Developer Edition):&lt;/i&gt;&lt;/p&gt;

&lt;p align="left"&gt;&lt;i&gt;&lt;strong&gt;2012 SP1 CUI&lt;/strong&gt; (build 11.0.3321 – November 2012)

    &lt;br /&gt;&lt;strong&gt;2008 R2 SP2 CU3&lt;/strong&gt; (build 10.50.4266 – October 2012)

    &lt;br /&gt;&lt;strong&gt;2008 SP3 CU8 &lt;/strong&gt;(build 10.0.5828 – November 2012)&lt;/i&gt;&lt;/p&gt;

&lt;p align="left"&gt;© 2012 Paul White – All Rights Reserved&lt;/p&gt;

&lt;p align="left"&gt;Twitter: &lt;a href="http://twitter.com/SQL_Kiwi"&gt;@SQL_Kiwi&lt;/a&gt; 

  &lt;br /&gt;Email: &lt;a href="mailto:SQLkiwi@gmail.com"&gt;SQLkiwi@gmail.com&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Cardinality Estimation Bug with Lookups</title><link>http://sqlblog.com/blogs/paul_white/archive/2012/10/15/cardinality-estimation-bug-with-lookups-in-sql-server-2008-onward.aspx</link><pubDate>Mon, 15 Oct 2012 06:25:05 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:45567</guid><dc:creator>Paul White</dc:creator><description>&lt;p align="left"&gt;Estimated row counts on key or RID lookups where a filtering predicate is applied can be wrong in SSMS execution plans.&amp;#160; This error does not affect the optimizer’s ultimate plan selection, but it does look odd.&amp;#160; There are other cases where estimated row counts are inconsistent (for defensible reasons) but the behaviour shown in this post in certainly a bug.&lt;/p&gt;  &lt;h2 align="left"&gt;SQL Server 2005&lt;/h2&gt;  &lt;p align="left"&gt;The following AdventureWorks sample query displays TransactionHistory information for ProductID #1 and the last three months of 2003 (if you are using a more recent version of AdventureWorks, you will need to change the year from 2003 to 2007):&lt;/p&gt;  &lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:'Courier New', courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    th.ProductID,&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    th.TransactionID,&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    th.TransactionDate&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; Production.TransactionHistory &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; th &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;WHERE&lt;/span&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    th.ProductID = 1 &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;AND&lt;/span&gt; th.TransactionDate &lt;span style="color:#0000ff;"&gt;BETWEEN&lt;/span&gt; &lt;span style="color:#006080;"&gt;'20030901'&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;AND&lt;/span&gt; &lt;span style="color:#006080;"&gt;'20031231'&lt;/span&gt;;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p align="left"&gt;The query plan is:&lt;/p&gt;

&lt;p align="left"&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_04ED36B9.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="Plain Plan" border="0" alt="Plain Plan" src="http://sqlblog.com/blogs/paul_white/image_thumb_6D728287.png" width="644" height="190" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p align="left"&gt;The execution flow is pretty straightforward.&amp;#160; The plan seeks a non-clustered index on the ProductID column to find rows where ProductID = 1.&amp;#160; This non-clustered index is keyed on ProductID alone, but the index also includes the TransactionID clustering key (to point to the parent row in the base table).&amp;#160; The index does not cover the query (the TransactionDate column is not present in the index) so a Key Lookup is required for the TransactionDate column.&amp;#160; The nested loops join drives a look up process such that each row from the Index Seek on ProductID = 1 results in a lookup in the clustered index to find the TransactionDate value for that row.&amp;#160; A final Filter operator passes only rows that meet the date range condition.&lt;/p&gt;

&lt;p align="left"&gt;The next diagram shows the same plan with cardinality estimates and extra details for the Key Lookup:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_0926DE9D.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="SQL Server 2005 plan" border="0" alt="SQL Server 2005 plan" src="http://sqlblog.com/blogs/paul_white/image_thumb_3750B48A.png" width="642" height="599" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p align="left"&gt;&lt;strong&gt;The cardinality estimate at the Index Seek is exactly correct.&lt;/strong&gt;&amp;#160; The table is not very large, there are up-to-date statistics associated with the index, so this is as expected.&amp;#160; If you run a query to find all rows in the TransactionHistory table for ProductID #1, 45 rows will indeed be returned.&lt;/p&gt;

&lt;p align="left"&gt;&lt;strong&gt;The estimate for the Key Lookup is exactly correct.&lt;/strong&gt;&amp;#160; Each lookup into the Clustered Index to find the Transaction Date is guaranteed to return exactly one row (each non-clustered index entry is associated with exactly one base table row).&amp;#160; The Key Lookup is expected to be executed 45 times (shown circled).&lt;/p&gt;

&lt;p align="left"&gt;&lt;strong&gt;The estimate for the Inner Join is exactly correct&lt;/strong&gt; – 45 rows from the seek joining to one row each time from the lookup, gives a total of 45 rows.&lt;/p&gt;

&lt;p align="left"&gt;&lt;strong&gt;The Filter estimate is also good: &lt;/strong&gt;SQL Server estimates that of the 45 rows entering the filter, &lt;strong&gt;16.9951&lt;/strong&gt; rows will match the specified range of transaction dates.&amp;#160; In reality, only 11 rows are produced by this query, but that small difference in estimates is quite normal and certainly nothing to worry about here.&amp;#160; You might like to keep that estimate of &lt;strong&gt;16.9951&lt;/strong&gt; rows in mind, however.&lt;/p&gt;

&lt;h2 align="left"&gt;SQL Server 2008 onward&lt;/h2&gt;

&lt;p align="left"&gt;The same query executed against an identical copy of AdventureWorks on SQL Server 2008 (or R2, or 2012) produces a quite different execution plan:&lt;/p&gt;

&lt;p align="left"&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_7B4472D4.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="SQL Server 2008 plan" border="0" alt="SQL Server 2008 plan" src="http://sqlblog.com/blogs/paul_white/image_thumb_06F9BA07.png" width="550" height="503" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p align="left"&gt;Instead of an explicit Filter to find rows with the requested date range, the optimizer has pushed the date predicate down to the Key Lookup (the Key Lookup now has a predicate on Transaction Date).&amp;#160; This is a good optimization in general terms; it makes sense to filter rows as early as possible.&amp;#160; &lt;strong&gt;Unfortunately, it has made a bit of a mess of the cardinality estimates in the process&lt;/strong&gt;.&amp;#160; The post-Filter estimate of &lt;strong&gt;16.9951&lt;/strong&gt; rows seen in the 2005 plan has been &lt;strong&gt;moved to the Key Lookup&lt;/strong&gt;.&amp;#160; Instead of estimating one row per lookup, the plan now suggests that 16.9951 rows will be produced by &lt;strong&gt;each&lt;/strong&gt; clustered index lookup – clearly not right!&lt;/p&gt;

&lt;p align="left"&gt;To my way of thinking, the execution plan cardinality estimates should look something like this:&lt;/p&gt;

&lt;p align="left"&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_05B1090C.png"&gt;&lt;img style="background-image:none;border-right-width:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://sqlblog.com/blogs/paul_white/image_thumb_66AAE56D.png" width="513" height="170" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p align="left"&gt;As shown, I personally prefer to see the inner side of a nested loops join estimate the number of rows per execution, but I understand I may be in a minority on this point.&amp;#160; If the estimate were aggregated over the expected number of executions, the inner-side estimate would be also be 16.9951 (45 executions * 0.37767 per execution).&lt;/p&gt;

&lt;h2 align="left"&gt;Cause&lt;/h2&gt;

&lt;p align="left"&gt;The query tree produced by the 2008+ optimizer looks much the same as the 2005 version – &lt;strong&gt;the explicit Filter is still present&lt;/strong&gt;.&amp;#160; However, a post-optimization rewrite occurs in the ‘copy out’ phase that removes the Filter and incorporates it in the Key Lookup seek, resulting in a residual predicate on that operator.&amp;#160; This rewrite applies to regular scans and seeks too (so all residual predicates on scans and seeks are a result of this late rewrite).&lt;/p&gt;

&lt;p align="left"&gt;I would like to thank Dima Piliugin (&lt;a href="https://twitter.com/SomewereSomehow" target="_blank"&gt;twitter&lt;/a&gt; | &lt;a href="http://www.somewheresomehow.ru" target="_blank"&gt;blog&lt;/a&gt;) for introducing me to undocumented trace flag 9130, which disables the rewrite from Filter + (Scan or Seek) to (Scan or Seek) + Residual Predicate.&amp;#160; Enabling this flag retains the Filter in the final execution plan, resulting in a SQL Server 2008+ plan that mirrors the 2005 version, with correct estimates.&lt;/p&gt;

&lt;p align="left"&gt;The bug is that this rewrite that does not correctly update cardinality estimates when the filter is pushed down to a lookup.&amp;#160; I should stress that the rewrite occurs after all cost-based decisions have been made, so the incorrect estimate just looks odd and makes plan analysis harder than it ought to be.&amp;#160; Cardinality estimates with regular scans and seeks appear to work correctly, as far as I can tell.&amp;#160; &lt;strong&gt;The bug applies to both RID lookups and Key Lookups&lt;/strong&gt; where a residual predicate is applied.&lt;/p&gt;

&lt;h2 align="left"&gt;Workarounds&lt;/h2&gt;

&lt;p align="left"&gt;Using the trace flag is not a workaround because (a) it is (very) undocumented and unsupported; and (b) it results in a less efficient plan where rows are filtered much later than is optimal.&amp;#160; One genuine workaround is to provide a covering non-clustered index (avoiding the lookup avoids the problem):&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:'Courier New', courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;CREATE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;INDEX&lt;/span&gt; nc1 &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;ON&lt;/span&gt; Production.TransactionHistory (ProductID) &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;INCLUDE&lt;/span&gt; (TransactionDate);&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p align="left"&gt;With the Transaction Date filter applied as a residual predicate in the same operator as the seek, the final estimate is again as expected:&lt;/p&gt;

&lt;p align="left"&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_2CBFBA9D.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://sqlblog.com/blogs/paul_white/image_thumb_406CA431.png" width="350" height="176" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p align="left"&gt;We could also force the use of the ultimate covering index (the clustered one) with a suitable table index hint:&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:'Courier New', courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    th.ProductID,&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    th.TransactionID,&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    th.TransactionDate&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; Production.TransactionHistory &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; th &lt;span style="color:#0000ff;"&gt;WITH&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;INDEX&lt;/span&gt;(1))&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;WHERE&lt;/span&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    th.ProductID = 1 &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;AND&lt;/span&gt; th.TransactionDate &lt;span style="color:#0000ff;"&gt;BETWEEN&lt;/span&gt; &lt;span style="color:#006080;"&gt;'20030901'&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;AND&lt;/span&gt; &lt;span style="color:#006080;"&gt;'20031231'&lt;/span&gt;;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p align="left"&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_113AB89A.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://sqlblog.com/blogs/paul_white/image_thumb_0FF61FBB.png" width="387" height="176" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p align="left"&gt;Again, the estimate is 16.9951 as expected.&lt;/p&gt;

&lt;h2 align="left"&gt;Fixed in SQL Sentry Plan Explorer build 7.2.42.0&lt;/h2&gt;

&lt;p align="left"&gt;After this post was published on October 15 2012 I was contacted by the SQL Sentry people to see if a good workaround could be incorporated in their free &lt;a href="http://www.sqlsentry.net/plan-explorer/sql-server-query-view.asp" target="_blank"&gt;Plan Explorer&lt;/a&gt; product.&amp;#160; I was happy to provide a little testing and general feedback during a process that ultimately resulted in a new build being released on 31 October 2012.&amp;#160; If only SSMS limitations could be addressed so quickly!&amp;#160; Once you upgrade to the new version, the plan displayed for our test query is:&lt;/p&gt;

&lt;p align="left"&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_657AE025.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://sqlblog.com/blogs/paul_white/image_thumb_7927C9B9.png" width="606" height="307" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p align="left"&gt;This is exactly the representation we would expect if the SQL Server bug did not exist (note that Plan Explorer aggregates estimated inner-side executions for you, and rounds to integer).&amp;#160; Well done to the SQL Sentry team, especially Brooke Philpott (&lt;a href="https://twitter.com/Macromullet" target="_blank"&gt;@MacroMullet&lt;/a&gt;).&lt;/p&gt;



&lt;h2 align="left"&gt;Summary&lt;/h2&gt;

&lt;p align="left"&gt;Providing a covering non-clustered index to avoid lookups for all possible queries is not always practical, and scanning the clustered index will rarely be the optimal choice either.&amp;#160; Nevertheless, these are the best workarounds we have today in SSMS.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p align="left"&gt;&lt;strong&gt;Watch out for poor cardinality estimates when a predicate is applied as part of a lookup&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p align="left"&gt;This particular cardinality estimation issue does not affect the final plan choice (the internal estimates are correct) but it does look odd and will confuse people when analysing query plans in SSMS.&amp;#160; If you think this situation should be improved, &lt;a href="http://connect.microsoft.com/SQLServer/feedback/details/767395/cardinality-estimation-error-with-pushed-predicate-on-a-lookup" target="_blank"&gt;please vote for this Connect item&lt;/a&gt;.&amp;#160; It will be interesting to see how long it takes to catch up with Plan Explorer.&lt;/p&gt;

&lt;p align="left"&gt;© 2012 Paul White – All Rights Reserved 
  &lt;br /&gt;

  &lt;br /&gt;twitter: &lt;a href="http://twitter.com/SQL_Kiwi"&gt;@SQL_Kiwi&lt;/a&gt; 

  &lt;br /&gt;email: &lt;a href="mailto:SQLkiwi@gmail.com"&gt;SQLkiwi@gmail.com&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Connect Digest : 2011-12-20</title><link>http://sqlblog.com/blogs/aaron_bertrand/archive/2011/12/20/connect-digest-2011-12-15.aspx</link><pubDate>Tue, 20 Dec 2011 16:55:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:39976</guid><dc:creator>AaronBertrand</dc:creator><description>&lt;p&gt;&lt;font size="4"&gt;Make SSMS start faster&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;A couple of years ago, I blogged about some ways to &lt;a href="http://www.onetooneglobal.com/otocorporate-posts/2009/06/25/making-management-studio-start-faster/" title="http://www.onetooneglobal.com/otocorporate-posts/2009/06/25/making-management-studio-start-faster/" target="_blank"&gt;make Management Studio start faster&lt;/a&gt;.
 With the latest builds of SQL Server 2012, it seems to be slower than 
ever, at least when starting SSMS for the first time after a reboot or 
install. So I've asked for them to do something in the background on 
Windows start-up to cover whatever initialization costs have to be paid 
on first launch. This is not something I expect to happen in this release, and perhaps it will be better by the time RTM comes around. But if you find it slow as well, in addition to voting, please post - in the comments on the Connect item - your machine config and how long it takes between clicking on the shortcut and being able to work. With enough stats in there they can probably extrapolate how much time is being lost waiting for the application to load. :-)&lt;br&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="http://connect.microsoft.com/SQLServer/feedback/details/714652/ssms-background-helper-pre-loader" title="http://connect.microsoft.com/SQLServer/feedback/details/714652/ssms-background-helper-pre-loader" target="_blank"&gt;#714652 : SSMS : Background helper / pre-loader &lt;/a&gt;&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;br&gt;&lt;font size="4"&gt;Let me opt out of product updates during setup&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;I am a big fan of streamlining slipstreaming (say that 5 times fast) - in other words, letting SQL Server setup check for product updates *before* installation, rather than the current manual process of cobbling together a setup package with a service pack and/or a cumulative update. In SQL Server 2012 we finally have this. Unfortunately, it is currently not an option; so, if your machine is not connected to the Internet for whatever reason, it hangs indefinitely on that step, trying desperately to go find those updated files. This needs to be an option so that you can proceed, even if you want to install RTM (e.g. for testing purposes) or you can't get to the Internet (now or ever). Sadly most software companies think that high speed Internet is enjoyed by all, when in fact a lot of folks can't get it or intentionally block their servers from any kind of external access.&lt;/p&gt;

&lt;blockquote&gt;&lt;a href="http://connect.microsoft.com/SQLServer/feedback/details/714661/scan-for-product-updates-hangs-on-isolated-system" title="http://connect.microsoft.com/SQLServer/feedback/details/714661/scan-for-product-updates-hangs-on-isolated-system" target="_blank"&gt;#714661 : Scan for Product Updates hangs on isolated system&lt;/a&gt; &lt;br&gt;&lt;/blockquote&gt;

&lt;p&gt;&lt;br&gt;&lt;font size="4"&gt;Add a time limit option to index reorg&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;Greg Low had an interesting idea to add a time limit to index reorg. Since the most work you'll ever lose upon cancelling is the reorganization of a single page, unlike a rebuild which has to roll back ALL of the work, it is a common practice to do a little bit of reorg at a time. But it is quite tedious to set up some kind of watchdog or to wait and kill the process manually. I can see how the syntax could work - a simple TIME_LIMIT option with the same input format as WAITFOR DELAY. So, for example, if you wanted to allow this reorg to work for up to 45 minutes and then stop:&lt;br&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;table bgcolor="#eeeeee" cellpadding="0" cellspacing="0"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre style="padding:10px 20px;font-size:12px;font-family:consolas,lucida console,courier new,courier;-moz-background-inline-policy:continuous;"&gt;&lt;font color="blue"&gt;ALTER INDEX &lt;/font&gt;&lt;font color="black"&gt;foo &lt;/font&gt;&lt;font color="blue"&gt;&lt;br&gt;  ON &lt;/font&gt;&lt;font color="black"&gt;dbo.bar&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&lt;font color="blue"&gt;REORGANIZE WITH &lt;/font&gt;&lt;font color="gray"&gt;(&lt;/font&gt;&lt;font color="blue"&gt;TIME_LIMIT &lt;/font&gt;= &lt;font color="red"&gt;'00:45:00'&lt;/font&gt;&lt;font color="gray"&gt;);&lt;/font&gt;&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/blockquote&gt;

&lt;p&gt;The Connect item is currently closed as won't fix, and I think that's partially because it's had only 2 votes in over a year. Please vote and add a comment indicating why this could be useful in your environment:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;a href="http://connect.microsoft.com/SQLServer/feedback/details/611158/index-reorganize-time-limit" title="http://connect.microsoft.com/SQLServer/feedback/details/611158/index-reorganize-time-limit" target="_blank"&gt;#611158 : Index Reorganize time limit&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;&lt;br&gt;&lt;font size="4"&gt;Gosh, I wish I could re-use that CTE&lt;/font&gt;&lt;/p&gt;&lt;p&gt;Several folks have filed suggestions to make it easier to work with the same query multiple times. Two of the popular ideas are temporary views and module-level table expressions. The current workaround of dumping data into a #temp table has significant overhead, and can still lead to errors if the same joins and where clauses need to be repeated over and over again. I like Erland Sommarskog's module-level table expressions idea best, but temporary views have a strong use case as well. I'm hoping to see some more comments and use cases on these items so that Microsoft can evaluate &lt;br&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;a href="http://connect.microsoft.com/SQLServer/feedback/details/343067/module-level-table-expressions" title="http://connect.microsoft.com/SQLServer/feedback/details/343067/module-level-table-expressions" target="_blank"&gt;#343067 : Module-level table expressions&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://connect.microsoft.com/SQLServer/feedback/details/640863/please-allow-creation-of-temporary-views" title="http://connect.microsoft.com/SQLServer/feedback/details/640863/please-allow-creation-of-temporary-views" target="_blank"&gt;#640863 : Please allow creation of temporary views&lt;/a&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://connect.microsoft.com/SQLServer/feedback/details/714617/t-sql-please-provide-temporary-views" title="http://connect.microsoft.com/SQLServer/feedback/details/714617/t-sql-please-provide-temporary-views" target="_blank"&gt;#714617 : [T-SQL] : Please provide temporary views&lt;/a&gt;&lt;br&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br&gt;&lt;font size="4"&gt;Truncate a table with foreign keys&lt;/font&gt;&lt;/p&gt;&lt;p&gt;We all know that you can't truncate a table that has foreign keys, but why should that be the case if all the referencing tables are empty (or have nullable referencing columns that are all NULL)? They've closed this one as won't fix, but if you can see the value in this for your environment, please add a comment indicating your use case, as they seem more than willing to revisit it...&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;a href="http://connect.microsoft.com/SQLServer/feedback/details/312074/permit-truncate-table-when-referencing-tables-are-empty" title="http://connect.microsoft.com/SQLServer/feedback/details/312074/permit-truncate-table-when-referencing-tables-are-empty" target="_blank"&gt;#312074 : Permit TRUNCATE TABLE when referencing tables are empty &lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;&lt;/blockquote&gt;</description></item><item><title>Want your bug fixed? File a good bug!</title><link>http://sqlblog.com/blogs/aaron_bertrand/archive/2011/09/20/want-your-bug-fixed-file-a-good-bug.aspx</link><pubDate>Tue, 20 Sep 2011 14:45:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:37620</guid><dc:creator>AaronBertrand</dc:creator><description>&lt;p&gt;In some circles I'm known as "the Connect guy" because I've filed a heck of a lot of suggestions and bugs that I've envisioned or encountered, and I'm often willing to file an issue on someone else's behalf. In other circles, for very much the same reasons, I'm probably known as "that annoying Connect guy." On and off over the past few years, I've assembled what I've called "Connect Digests" here on this blog, calling out some of the issues that have been filed that I've deemed as deserving attention. At some points these digests have been more regular than others, and that is totally driven by travel, schedule and workload.&lt;/p&gt;

&lt;p&gt;Today I thought I would share a little bit of wisdom with my fellow (and potential) bug-filers. I do see a lot of bugs that get closed as Not Reproducible ("no-repro") or Won't Fix, and I don't think that they all had to be closed that way. Part of the problem can often be pointed back to the quality of the bug itself. I'm not going to name names or call out any specific "bad" bugs, but just wanted to give some hints about what they are looking for. Note that for bugs you should be able to re-open them even if they get closed, but only do so if you have new information to add, not just because you didn't like the decision.&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="4"&gt;If your bug comes back as Not Reproducible&lt;br&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;Try to ensure that you have included complete information about the repro. If there is a crash, capture the detailed stack trace information from the event log or the application's dialog (e.g. SSMS has these details). If screen shots help with the repro, include them. If there are certain "non-standard" aspects of your environment, such as a non-default collation, different compatibility mode, database name that is a keyword, different operating system language, etc., it is possible that those differences are influential in manifesting the bug and, without that information, it might not be possible for Microsoft to repro (because they aren't going to walk through your steps using a full matrix of every possible test combination). Without full, consistent and reproducible steps to exhibit the problem, it is also impossible to know whether you've fixed the problem, and can also be difficult to determine how effective the fix is and whether or not it caused regression elsewhere. &lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;/p&gt;&lt;p&gt;&lt;font size="4"&gt;If your bug/suggestion comes back as Won't Fix &lt;br&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Hopefully there is a comment that goes along with it, and the comment will explain why the issue won't be fixed. Sometimes it is just not practical to fix a bug or implement a suggestion, or to do so in the current development cycle. The following factors are all used to guide where a bug or suggestion ends up on the pipeline:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;how to reproduce the problem&lt;/li&gt;
&lt;li&gt;the frequency the problem occurs&lt;/li&gt;
&lt;li&gt;the likelihood of the problem occurring (number of customers potentially affected)&lt;br&gt;&lt;/li&gt;
&lt;li&gt;the actual impact on users&lt;/li&gt;
&lt;li&gt;the root cause&lt;/li&gt;
&lt;li&gt;the cost and risk of fixing it (e.g. backward compatibility)&lt;br&gt;&lt;/li&gt;
&lt;li&gt;available work-arounds&lt;/li&gt;
&lt;/ul&gt;
Yes, they certainly understand that an issue might be important to &lt;b&gt;you&lt;/b&gt;; however, there are many other factors to consider. Depending on the reason(s) stated in the comment(s) by Microsoft, you might want to come back armed with more compelling information, or more people stating their business case qualitatively (see below).&lt;br&gt;&lt;br&gt;
&lt;p&gt;&lt;font size="4"&gt;If you haven't filed your bug/suggestion yet (or it's not yours)&lt;/font&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;Please keep the above in mind. Also note that the qualitative information is at least as important, and often more so, than the quantitative information. In other words, if you just state that x is broken, needs to be fixed, and look at all these votes that support it, that is not necessarily enough to convince Microsoft that it needs to be fixed. In the description of your bug, or in a comment on someone else's, state *why* it needs to be fixed. A real business case that demonstrates significant impact on a customer goes a heck of a lot further than a few extra votes. If your arguments involve standards compliance or keeping up with a competitive RDBMS product, it certainly can't hurt to include that information as well. If you have additional information that explains why the issue hurts, or how the workaround is painful, this can be factored into the decision (unlike an extra up-vote, which to Microsoft is just an &amp;lt;aol&amp;gt;me too&amp;lt;/aol&amp;gt;). Including this data can only make it more likely that the item will be seriously considered. &lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="4"&gt;Summary&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Connect can be an invaluable tool in getting feedback back to Microsoft and affecting change in SQL Server. It can also be quite frustrating if the flow of information - in either direction - is not the highest in quality. I hope I've given you some things to think about to at least improve one direction of that flow.&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;/p&gt;
&lt;span style="color:#1F497D;"&gt;&lt;/span&gt;</description></item><item><title>Connect Digest : 2011-04-25</title><link>http://sqlblog.com/blogs/aaron_bertrand/archive/2011/04/25/connect-digest-2011-04-25.aspx</link><pubDate>Mon, 25 Apr 2011 10:54:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:35078</guid><dc:creator>AaronBertrand</dc:creator><description>&lt;p&gt;I wanted to change it up a little this week. In every digest, I've pointed out a set of Connect items that I believe deserve more attention. What I fail to point out every week is the number of Connect items that actually get resolved with a fix. These are even less visible than the active requests, but I think they deserve some attention as well. Why? Well, almost every single comment on Connect is a neutral or negative comment. I think we could all be better about going back to some of these items and thanking Microsoft - not so much for the bugs, which they should be fixing regardless, but more so for the suggestions that we make.&lt;/p&gt;
&lt;p&gt;Here are a few items where the issue has been addressed. I call these "Connect wins":&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="http://connect.microsoft.com/SQL/feedback/ViewFeedback.aspx?FeedbackID=424800" title="http://connect.microsoft.com/SQL/feedback/ViewFeedback.aspx?FeedbackID=424800" target="_blank"&gt;#424800 : SSMS : Expose "Connect to Server" MRU list to users&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://connect.microsoft.com/SQLServer/feedback/details/484732" title="http://connect.microsoft.com/SQLServer/feedback/details/484732" target="_blank"&gt;#484732 : sqlps and PowerShell V2 Issues&lt;/a&gt; (granted, fixed for 2008, but no word on 2008 R2 yet) &lt;br&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://connect.microsoft.com/SQL/feedback/ViewFeedback.aspx?FeedbackID=615766" title="http://connect.microsoft.com/SQL/feedback/ViewFeedback.aspx?FeedbackID=615766" target="_blank"&gt;#615766 : [Denali SSMS] : Execution plan tooltip causes very slow behavior&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://connect.microsoft.com/SQLServer/feedback/details/615767/denali-engine-regression-in-query-hint-behavior" title="http://connect.microsoft.com/SQLServer/feedback/details/615767/denali-engine-regression-in-query-hint-behavior" target="_blank"&gt;#615767 : [Denali Engine] : Regression in query hint behavior&lt;/a&gt;&amp;nbsp; &lt;br&gt;&lt;/p&gt;
&lt;a href="http://connect.microsoft.com/SQL/feedback/ViewFeedback.aspx?FeedbackID=621445" title="http://connect.microsoft.com/SQL/feedback/ViewFeedback.aspx?FeedbackID=621445" target="_blank"&gt;#621445 : Extended Events to Trace Mapping Tables in sys schema in Master&lt;/a&gt;
&lt;p&gt;&lt;a href="http://connect.microsoft.com/SQL/feedback/ViewFeedback.aspx?FeedbackID=621656" title="http://connect.microsoft.com/SQL/feedback/ViewFeedback.aspx?FeedbackID=621656" target="_blank"&gt;#621656 : [SSIS Denali] Synchronous Executions&lt;/a&gt; (though closed as fixed, no official comment from Microsoft)&lt;/p&gt;
&lt;p&gt;&lt;a href="http://connect.microsoft.com/SQL/feedback/ViewFeedback.aspx?FeedbackID=631373" title="http://connect.microsoft.com/SQL/feedback/ViewFeedback.aspx?FeedbackID=631373" target="_blank"&gt;#631373 : Denali - Transaction_Log Extended Event Returning Incorrect Data&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
Now, there is still plenty of Connect activity that seems to get ignored completely, and several cases where the last comment (four years ago) was, "We'll look at that for the next release." Still others (like &lt;a href="http://connect.microsoft.com/SQL/feedback/ViewFeedback.aspx?FeedbackID=524769" title="http://connect.microsoft.com/SQL/feedback/ViewFeedback.aspx?FeedbackID=524769" target="_blank"&gt;#524769&lt;/a&gt;) have lots of dialog, but almost all of it is useless, and of course there are countless items that have been closed as "Won't Fix" or "By [questionable] Design." But for the vast amount of content these folks have to sort through, I think it's worthwhile to thank them even for small victories. 
&lt;p&gt;Have a Connect win to share? Please post in the comments! &lt;/p&gt;
&lt;p&gt;&amp;nbsp; &lt;br&gt;&lt;/p&gt;</description></item><item><title>A better way to search Connect</title><link>http://sqlblog.com/blogs/aaron_bertrand/archive/2011/01/06/a-better-way-to-search-connect.aspx</link><pubDate>Thu, 06 Jan 2011 14:21:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:32377</guid><dc:creator>AaronBertrand</dc:creator><description>&lt;p&gt;I recently spotted a comment from Microsoft on a &lt;a title="http://connect.microsoft.com/SQLServer/feedback/details/358576/" target="_blank" href="http://connect.microsoft.com/SQLServer/feedback/details/358576/"&gt;Connect item with 13 total up-votes&lt;/a&gt;.&amp;nbsp; The comment went something like, "wow, due to the explosive response to this issue, we're going to deal with it right away."&amp;nbsp; Okay, it wasn't that emphatic, it was actually: "I've brought the MVP customer vote count to the attention of dev, and a new owner of this DMV says he will dig up some info for us." Still, knowing that I had seen other items with a much stronger response and barely a note of acknowledgment (never mind a pledge to actually act in any way), I performed a search.&amp;nbsp; I started with a search for "SSMS" in my own feedback and was overloaded.&amp;nbsp; So I used the advanced search to whittle it down.&amp;nbsp; I tried over 100 votes and didn't get any.&amp;nbsp; I started getting results (well, 1) when I scaled back to 70:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&amp;nbsp;&lt;img width="460" border="1" height="692" src="http://sqlblog.com/files/folders/32373/download.aspx"&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Then I scaled back to 50, and nothing significantly changed. &amp;nbsp;When I scaled back to 30, though, I saw a really, well, interesting result:&lt;/p&gt;&lt;p style="margin-left:40px;"&gt;&lt;img width="488" border="1" height="687" src="http://sqlblog.com/files/folders/32374/download.aspx"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Why is this interesting?&amp;nbsp; Well, the item with 78 up-votes doesn't show up in a search for &amp;gt;= 70.&amp;nbsp; It also doesn't show up in a search for &amp;gt;= 50.&amp;nbsp; But when you lower the threshold to 30, it suddenly appears.&amp;nbsp; Another interesting thing is that no matter what number I put into the vote count, items (such as &lt;a title="https://connect.microsoft.com/SQLServer/feedback/details/311079" target="_blank" href="https://connect.microsoft.com/SQLServer/feedback/details/311079"&gt;#311079&lt;/a&gt;) with more than 100 votes never show up:&lt;/p&gt;&lt;p style="margin-left:40px;"&gt;&lt;img width="638" border="1" height="191" src="http://sqlblog.com/files/folders/32375/download.aspx"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;This is just the most recent bit of fascinating search logic I've discovered on Connect; there are many others over the past few years that have really made me shake my head.&amp;nbsp; I've asked multiple times if we could get an API into the data to write our own searches, or be able to store backups of the data so that we can load them on our own systems and run our own searches.&amp;nbsp; The response was always, predictably, "no, not cool."&amp;nbsp; And they wonder why activity on Connect has dwindled (well, there are several reasons for that, which I may highlight in future blog posts).&lt;br&gt;&lt;/p&gt;&lt;p&gt;Fast forward to last week, when Aaron Nelson (&lt;a title="http://sqlvariant.com/wordpress/" target="_blank" href="http://sqlvariant.com/wordpress/"&gt;blog&lt;/a&gt; | &lt;a title="http://twitter.com/sqlvariant" target="_blank" href="http://twitter.com/sqlvariant"&gt;twitter&lt;/a&gt;) and Nic Cain (&lt;a title="http://www.englishtosql.com/" target="_blank" href="http://www.englishtosql.com/"&gt;blog&lt;/a&gt; | &lt;a title="http://twitter.com/anonythemouse" target="_blank" href="http://twitter.com/anonythemouse"&gt;twitter&lt;/a&gt;) let me in on a little secret - they were loading Connect's SQL Server data into their own SQL Server database, via the &lt;a title="https://connect.microsoft.com/rss/68/RecentFeedbackForConnection.xml" target="_blank" href="https://connect.microsoft.com/rss/68/RecentFeedbackForConnection.xml"&gt;RSS feed&lt;/a&gt;.&amp;nbsp; Nic is &lt;a title="http://www.englishtosql.com/english-to-sql-blog/2011/1/5/loading-microsoft-connect-items-to-a-databaseintro.html" target="_blank" href="http://www.englishtosql.com/english-to-sql-blog/2011/1/5/loading-microsoft-connect-items-to-a-databaseintro.html"&gt;starting a blog series about it&lt;/a&gt;, but the important points are:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;You can now get more direct access to the data.&amp;nbsp; Rob Farley (&lt;a title="http://sqlblog.com/blogs/rob_farley/default.aspx" target="_blank" href="http://sqlblog.com/blogs/rob_farley/default.aspx"&gt;blog&lt;/a&gt; | &lt;a title="http://twitter.com/rob_farley" target="_blank" href="http://twitter.com/rob_farley"&gt;twitter&lt;/a&gt;), for example, has loaded up the Denali bugs into a &lt;a title="http://pivot.lobsterpot.com.au/ConnectItems" target="_blank" href="http://pivot.lobsterpot.com.au/ConnectItems"&gt;pivot collection&lt;/a&gt;, allowing you to do lots of real-time visualization against a wide variety of filters.&amp;nbsp; You can also click through to items that interest you.&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;/li&gt;&lt;li&gt;Aaron has &lt;a title="http://sqlvariant.com/wordpress/index.php/2011/01/is-the-connect-feed-for-sql-server-in-your-reader/" target="_blank" href="http://sqlvariant.com/wordpress/index.php/2011/01/is-the-connect-feed-for-sql-server-in-your-reader/"&gt;posted a PowerShell script&lt;/a&gt; (you weren't expecting anything other than PowerShell, were you?) that will give you read-only access to the data, empowering you to write your own queries against it.&amp;nbsp; I've already used it to run the following, where I was much happier with the results:&lt;/li&gt;&lt;/ol&gt;&lt;blockquote&gt;&lt;table bgcolor="#eeeeee" cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;pre style="padding:10px 20px;font-size:12px;font-family:consolas,lucida console,courier new,courier;-moz-background-inline-policy:continuous;"&gt;&lt;font style="color:blue;"&gt;SELECT &lt;/font&gt;*&lt;font style="color:blue;"&gt; FROM&lt;/font&gt; dbo.ConnectItems&lt;br&gt;&lt;font style="color:blue;"&gt;  WHERE&lt;/font&gt; Author = &lt;font color="red"&gt;'aaronbertrand'&lt;/font&gt;&lt;br&gt;&lt;font style="color:blue;"&gt;  AND&lt;/font&gt; UpVoteCount &amp;gt;= 30;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/blockquote&gt;&lt;p style="margin-left:40px;"&gt;Note, though, that the data is not currently complete - the loading is still in process. So I'm not 100% happy with the results, but I know they'll get there.&lt;br&gt;&lt;/p&gt;&lt;p&gt;If you want to stay on top of Connect items for SQL Server, I strongly recommend adding the &lt;a title="https://connect.microsoft.com/rss/68/RecentFeedbackForConnection.xml" target="_blank" href="https://connect.microsoft.com/rss/68/RecentFeedbackForConnection.xml"&gt;new items&lt;/a&gt; and &lt;a title="https://connect.microsoft.com/rss/68/RecentlyModifiedFeedbackForConnection.xml" target="_blank" href="https://connect.microsoft.com/rss/68/RecentlyModifiedFeedbackForConnection.xml"&gt;recently modified items&lt;/a&gt; feeds to your favorite RSS reader.&amp;nbsp; In combination with easier searching, I find this quite useful.&lt;br&gt;&lt;/p&gt;&amp;nbsp;&lt;br&gt;</description></item><item><title>An Interesting MERGE Bug</title><link>http://sqlblog.com/blogs/paul_white/archive/2010/08/03/another-interesting-merge-bug.aspx</link><pubDate>Tue, 03 Aug 2010 17:30:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:27573</guid><dc:creator>Paul White</dc:creator><description>&lt;p&gt;&lt;i&gt;Summary: Investigating an optimiser transformation that exposes a bug in SQL Server’s MERGE implementation.&lt;/i&gt;&lt;/p&gt;  &lt;p&gt;I came across a &lt;a href="https://connect.microsoft.com/SQLServer/feedback/details/581548/sql2008-r2-merge-statement-with-only-table-variables-fails"&gt;Connect item&lt;/a&gt; today (by fellow SQL Server Central member ‘ALZDBA’) describing how using a combination of relatively new features can produce incorrect results or even an access violation inside SQL Server.&lt;/p&gt;  &lt;h4&gt;Reproducing the bug&lt;/h4&gt;  &lt;p&gt;We’ll look first at how MERGE can produce incorrect an output.&amp;#160; We’ll need two tables: one that contains two rows of existing data; and a second that contains four rows of change information.&amp;#160; The overall process looks like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/MergeOverview_25CC1C68.png"&gt;&lt;img style="border-right-width:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;margin-left:auto;border-left-width:0px;margin-right:auto;" title="Merge-Overview" border="0" alt="Merge-Overview" src="http://sqlblog.com/blogs/paul_white/MergeOverview_thumb_36D56BAD.png" width="627" height="177" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;This is a classic MERGE (or “upsert”) requirement.&amp;#160; If the row already exists, the new value is added to it, otherwise a new row is inserted.&amp;#160; Here’s the code to generate the sample tables and data:&lt;/p&gt;  &lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:'Courier New', courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;   &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;&lt;span style="color:#0000ff;"&gt;DECLARE&lt;/span&gt; @Target&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;TABLE&lt;/span&gt;   (&lt;br /&gt;        row_id  &lt;span style="color:#0000ff;"&gt;INTEGER&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;NOT&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;NULL&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;PRIMARY&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;KEY&lt;/span&gt;,&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;   &lt;span style="color:#0000ff;"&gt;INTEGER&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;NOT&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;NULL&lt;/span&gt;&lt;br /&gt;        );&lt;br /&gt; &lt;br /&gt;&lt;span style="color:#0000ff;"&gt;DECLARE&lt;/span&gt; @Delta&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;TABLE&lt;/span&gt;   (&lt;br /&gt;        row_id  &lt;span style="color:#0000ff;"&gt;INTEGER&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;NOT&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;NULL&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;PRIMARY&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;KEY&lt;/span&gt;,&lt;br /&gt;        delta   &lt;span style="color:#0000ff;"&gt;INTEGER&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;NOT&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;NULL&lt;/span&gt;&lt;br /&gt;        );&lt;br /&gt; &lt;br /&gt;&lt;span style="color:#008000;"&gt;-- Existing records (1 &amp;amp; 3)&lt;/span&gt;&lt;br /&gt;INSERT  @Target&lt;br /&gt;        (row_id, &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;)&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;VALUES&lt;/span&gt;  (1, 1),&lt;br /&gt;        (3, 3);&lt;br /&gt; &lt;br /&gt;&lt;span style="color:#008000;"&gt;-- Change table:&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#008000;"&gt;-- Updates rows 1 &amp;amp; 3&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#008000;"&gt;-- Inserts rows 2 &amp;amp; 4&lt;/span&gt;&lt;br /&gt;INSERT  @Delta&lt;br /&gt;        (row_id, delta)&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;VALUES&lt;/span&gt;  (1, 10),&lt;br /&gt;        (2, 20),&lt;br /&gt;        (3, 30),&lt;br /&gt;        (4, 40);&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;We can easily write a MERGE query to perform the actions needed.&amp;#160; Let’s also include an OUTPUT clause to show the effects on each row:&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:'Courier New', courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;MERGE   @Target T&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;USING&lt;/span&gt;   @Delta D&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;ON&lt;/span&gt;  D.row_id = T.row_id&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;WHEN&lt;/span&gt;    MATCHED &lt;span style="color:#0000ff;"&gt;THEN&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;UPDATE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SET&lt;/span&gt; T.&lt;span style="color:#0000ff;"&gt;value&lt;/span&gt; += D.delta&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;WHEN&lt;/span&gt;    &lt;span style="color:#0000ff;"&gt;NOT&lt;/span&gt; MATCHED &lt;span style="color:#0000ff;"&gt;BY&lt;/span&gt; TARGET &lt;span style="color:#0000ff;"&gt;THEN&lt;/span&gt; &lt;br /&gt;        INSERT &lt;span style="color:#0000ff;"&gt;VALUES&lt;/span&gt; (D.row_id, D.delta)&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;OUTPUT&lt;/span&gt;  D.row_id,&lt;br /&gt;        $&lt;span style="color:#0000ff;"&gt;action&lt;/span&gt;,&lt;br /&gt;        DELETED.&lt;span style="color:#0000ff;"&gt;value&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; old_value,&lt;br /&gt;        INSERTED.&lt;span style="color:#0000ff;"&gt;value&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; new_value;&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;If we examine the @Target table after executing this query, we get exactly the results shown in the diagram.&amp;#160; All good so far.&amp;#160; The problem comes when we look at the rows produced by the OUTPUT clause:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/MERGEOutput_4D9743E7.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="MERGE-Output" border="0" alt="MERGE-Output" src="http://sqlblog.com/blogs/paul_white/MERGEOutput_thumb_1AC73D73.png" width="234" height="97" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When the action is ‘INSERT’, the &lt;i&gt;new_value&lt;/i&gt; column contains an incorrect value.&amp;#160; Instead of reporting the value actually inserted into the target table, it repeats the value associated with the last UPDATE operation.&amp;#160; If we change the data so that multiple INSERTs are performed after the UPDATE, all the INSERTs get the same &lt;i&gt;new_value&lt;/i&gt; associated with the prior UPDATE.&amp;#160; The @Target table always contains the correct data – it’s just that the OUTPUT clause disagrees.&lt;/p&gt;

&lt;h4&gt;The Query Plan&lt;/h4&gt;

&lt;p&gt;The original Connect item states that this issue only affects table variables, but there’s more to see here.&amp;#160; Let’s start by taking a look at the execution plan for the sample MERGE statement above (click to enlarge):&lt;/p&gt;

&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/MergePlan_51A4226A.png"&gt;&lt;img style="border-right-width:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;margin-left:auto;border-left-width:0px;margin-right:auto;" title="Merge-Plan" border="0" alt="Merge-Plan" src="http://sqlblog.com/blogs/paul_white/MergePlan_thumb_37CFEC3B.png" width="660" height="83" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have omitted several Compute Scalar iterators to make it easier to see what’s going on.&amp;#160; There’s a scan of the @Delta table, followed by an Insert to the @Target table, and finally a Merge into the @Target table.&amp;#160; If you are familiar with the sort of plans MERGE normally produces, you might find that arrangement a bit odd.&amp;#160; Even if MERGE is new to you, you might think that an Insert followed by a Merge is surprising.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;In a normal MERGE, we would expect to see an outer join between the source and target tables, followed by a Merge:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/paul_white/image_0E5BAAFB.png"&gt;&lt;img style="border-right-width:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;margin-left:auto;border-left-width:0px;margin-right:auto;" title="image" border="0" alt="image" src="http://sqlblog.com/blogs/paul_white/image_thumb_7E4F6CF4.png" width="660" height="154" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;SQL Server performs an outer join so the Clustered Index Merge knows whether the current row already exists in the target table or not.&amp;#160; If it exists, it is updated, otherwise a new row is inserted.&lt;/p&gt;

&lt;p&gt;If you’ve been following my &lt;a href="http://sqlblog.com/blogs/paul_white/archive/2010/07/29/inside-the-optimiser-constructing-a-plan.aspx"&gt;recent series&lt;/a&gt; on optimiser internals, you might suspect that the optimiser has applied a transformation to get the join-less plan, and the two plans are somehow logically identical.&amp;#160; You would be right – the rule in question is LOJPrjGetToApply (Left Outer Join, Project Get to Apply).&lt;/p&gt;

&lt;h4&gt;The Optimisation&lt;/h4&gt;

&lt;p&gt;The idea behind the optimisation is to read a row from the @Delta table and immediately try to insert it into the @Target table.&amp;#160; If that succeeds, the row didn’t already exist, and no further work is required.&lt;/p&gt;

&lt;p&gt;If the row did exist, the PRIMARY KEY on @Target will cause a duplicate key violation to occur.&amp;#160; The relational engine suppresses that error, and execution continues on down to the Clustered Index Merge iterator, which performs the necessary UPDATE.&lt;/p&gt;

&lt;p&gt;This is a very useful (and perfectly safe) query optimisation &lt;i&gt;if&lt;/i&gt; the conditions are right.&amp;#160; There are rather a lot of conditions, the most important of which are:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The target of the merge must have a suitable &lt;i&gt;clustered&lt;/i&gt; unique or primary key constraint &lt;/li&gt;

  &lt;li&gt;The changes (delta) table must have some sort of unique constraint (can be non-clustered) on the join column &lt;/li&gt;

  &lt;li&gt;The plan must be already using a nested loops join &lt;/li&gt;

  &lt;li&gt;The MERGE must include a NOT MATCHED condition plus at least one MATCHED clause &lt;/li&gt;

  &lt;li&gt;Equivalent columns in the two tables must have exactly the same type – no implicit conversions allowed &lt;/li&gt;

  &lt;li&gt;There can be no chance of a constraint violation – including NOT NULL constraints &lt;/li&gt;

  &lt;li&gt;The query must not update the clustered key &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If any of the required conditions do not apply, the optimisation is not performed, and the query plan retains the outer join.&lt;/p&gt;

&lt;p&gt;In order for the MERGE to return incorrect results:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The MERGE target must be a temporary table (the delta table can be anything) &lt;/li&gt;

  &lt;li&gt;The optimiser must produce a final plan that includes the transformation described above &lt;/li&gt;

  &lt;li&gt;The MERGE statement must include an OUTPUT clause that references the &lt;i&gt;inserted&lt;/i&gt; pseudo table &lt;/li&gt;

  &lt;li&gt;The query has to perform an INSERT row action after an UPDATE (in clustered index order) &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Importantly, it is only rows that result in an INSERT that cause problems.&amp;#160; If only UPDATE or DELETE operations result from the MERGE, everything works perfectly – even with a table variable as the target.&lt;/p&gt;

&lt;h4&gt;Producing an Access Violation&lt;/h4&gt;

&lt;p&gt;The example data given for the @Delta table was carefully constructed to ensure that incorrect results were returned.&amp;#160; With different sample data, we will get an Access Violation (AV) which terminates the connection and produces a stack dump on the SQL Server.&lt;/p&gt;

&lt;p&gt;The simplest way (based on the test rig above) is to change the @Delta table contents to just include a single row that will result in an INSERT:&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:'Courier New', courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;INSERT  @Delta&lt;br /&gt;        (row_id, delta)&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;VALUES&lt;/span&gt;  (2, 2);&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;There is no row in @Target with &lt;i&gt;row_id&lt;/i&gt; = 2, so this results in an INSERT.&lt;/p&gt;

&lt;p&gt;To expand our test rig to encompass DELETE operations, we need to add an extra condition to the original MERGE statement.&amp;#160; The new code will delete a record if its value is zero after applying the deltas:&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:'Courier New', courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;MERGE   @Target T&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;USING&lt;/span&gt;   @Delta D&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;ON&lt;/span&gt;  D.row_id = T.row_id&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;WHEN&lt;/span&gt;    MATCHED             &lt;span style="color:#008000;"&gt;-- New --&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;AND&lt;/span&gt;     T.&lt;span style="color:#0000ff;"&gt;value&lt;/span&gt; = -D.delta  &lt;span style="color:#008000;"&gt;-- New --&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;THEN&lt;/span&gt;    &lt;span style="color:#0000ff;"&gt;DELETE&lt;/span&gt;              &lt;span style="color:#008000;"&gt;-- New --&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;WHEN&lt;/span&gt;    MATCHED &lt;span style="color:#0000ff;"&gt;THEN&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;UPDATE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SET&lt;/span&gt; T.&lt;span style="color:#0000ff;"&gt;value&lt;/span&gt; += D.delta&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;WHEN&lt;/span&gt;    &lt;span style="color:#0000ff;"&gt;NOT&lt;/span&gt; MATCHED &lt;span style="color:#0000ff;"&gt;BY&lt;/span&gt; TARGET &lt;span style="color:#0000ff;"&gt;THEN&lt;/span&gt; &lt;br /&gt;        INSERT &lt;span style="color:#0000ff;"&gt;VALUES&lt;/span&gt; (D.row_id, D.delta)&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;OUTPUT&lt;/span&gt;  D.row_id,&lt;br /&gt;        $&lt;span style="color:#0000ff;"&gt;action&lt;/span&gt;,&lt;br /&gt;        DELETED.&lt;span style="color:#0000ff;"&gt;value&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; old_value,&lt;br /&gt;        INSERTED.&lt;span style="color:#0000ff;"&gt;value&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; new_value;&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;With that modification in place, the following values in the @Delta table will update the row with &lt;i&gt;row_id&lt;/i&gt; = 1, and delete the one with &lt;i&gt;row_id&lt;/i&gt; = 3:&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:'Courier New', courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;INSERT  @Delta&lt;br /&gt;        (row_id, delta)&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;VALUES&lt;/span&gt;  (1, 10),&lt;br /&gt;        (3, -3);&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;This combination works correctly because there is no INSERT operation.&amp;#160; Any number of UPDATEs and DELETEs can be performed without issue, so long as no INSERTs occur.&lt;/p&gt;

&lt;h4&gt;Workarounds&lt;/h4&gt;

&lt;p&gt;The easiest workarounds involve preventing the query optimisation from happening in the first place.&amp;#160; This is quite easy since there are so many conditions for it to apply.&amp;#160; One way is to prevent the plan from using a nested loops join with an OPTION (HASH JOIN, MERGE JOIN) hint.&amp;#160; There are many other alternatives in the same vein, of course.&lt;/p&gt;

&lt;p&gt;A second workaround is to apply Trace Flag 8758 – unfortunately this disables a number of optimisations, not just the one above, so it’s not really recommended for long term use.&lt;/p&gt;

&lt;p&gt;Third, we could turn off the LOJPrjGetToApply rule (again, see my previous optimiser posts) but that could also negatively affect other plans that benefit from the optimisation.&lt;/p&gt;

&lt;h4&gt;Final Thoughts&lt;/h4&gt;

&lt;p&gt;This isn’t a bug that will affect everyone, but it does show that your chances of turning up a bug increase as you push the limits of the optimiser and fairly new features like MERGE.&lt;/p&gt;

&lt;p&gt;It will be interesting to see how the Connect item goes: will Microsoft fix this, or will they just say that MERGE was never intended for use with table variables?&amp;#160; We’ll have to wait and see.&lt;/p&gt;

&lt;p&gt;My thanks to ‘ALZDBA’ for reporting this problem.&amp;#160; Personally, I see the prospect of returning incorrect data from the OUTPUT clause as more serious than the access violation.&amp;#160; The OUTPUT clause is often used to record audit information, so producing incorrect data with no error seems undesirable.&amp;#160; I would encourage you all to form your own view on this bug, and &lt;a href="https://connect.microsoft.com/SQLServer/feedback/details/581548/sql2008-r2-merge-statement-with-only-table-variables-fails"&gt;vote&lt;/a&gt; on it accordingly.&lt;/p&gt;

&lt;p&gt;© Paul White
  &lt;br /&gt;email: &lt;a href="mailto:SQLkiwi@gmail.com"&gt;SQLkiwi@gmail.com&lt;/a&gt;

  &lt;br /&gt;twitter: &lt;a href="http://twitter.com/SQL_Kiwi"&gt;@SQL_Kiwi&lt;/a&gt;&lt;/p&gt;</description></item><item><title>SSMS : Which parts do you love? Which parts do you hate?</title><link>http://sqlblog.com/blogs/aaron_bertrand/archive/2010/06/22/ssms-which-parts-do-you-love-which-parts-fo-you-hate.aspx</link><pubDate>Wed, 23 Jun 2010 00:56:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:26377</guid><dc:creator>AaronBertrand</dc:creator><description>&lt;p&gt;I find myself categorizing a subset of SSMS features ranging from "must have" features to "cringe when they are mentioned."&amp;nbsp; I'll try to summarize the standouts for you here, then ask you these questions: Which parts of SSMS do you rely on? Which do you wish were not there at all?&lt;br&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;The "I almost always use it to get the task done." variety&lt;/b&gt;&lt;br&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;SQL Server Agent's Job / Job Step Editor.&amp;nbsp; While not pretty, the wizard does make quick work of creating jobs with several steps, multiple schedules, and various execution paths.&amp;nbsp; (Let's just pretend the 2008 R2 version isn't a no-op &lt;a href="https://connect.microsoft.com/SQLServer/feedback/details/557402/ssms-can-no-longer-create-or-edit-job-steps" title="https://connect.microsoft.com/SQLServer/feedback/details/557402/ssms-can-no-longer-create-or-edit-job-steps" target="_blank"&gt;due to a debilitating bug&lt;/a&gt;.)&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;/li&gt;&lt;li&gt;Profiler.&amp;nbsp; Similar to the job procedures, I am unlikely to ever get the hang of scripting a server-side trace from memory.&amp;nbsp; So, I use the profiler UI to set up the trace details, then save the script for future use.&amp;nbsp; If I have to run a slightly different server-side trace, I can use the same script with minimal changes; but in many cases it is just as quick to use the UI again and start from scratch.&amp;nbsp; (Technically, I guess this isn't part of SSMS, but it is certainly a management UI that has had its share of criticism over the years.)&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;Right-click object &amp;gt; Modify, or Script as ALTER to New Window.&amp;nbsp; This is by far the quickest way for me to get at the *current* version that is deployed, and when I am done testing my revisions against the dev server, I can then move the changes to source control.&amp;nbsp; I see a lot of people using sp_helptext or manually selecting from syscomments / sys.sql_modules / OBJECT_DEFINITION(), but this can involve several more steps to get the code into suitable (and more importantly, maintainable) shape.&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;/li&gt;&lt;li&gt;Registered servers.&amp;nbsp; These are a god-send, especially since I've learned to export carefully constructed nodes and share them across all machines.&amp;nbsp; I wish the tool in general was more consistent at remembering passwords depending on how I've initiated or switch a connection, but that's another story I suppose.&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;b&gt;The "I will use it if I have to, but usually feel icky and prefer better alternatives." variety&lt;/b&gt;&lt;br&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Table Designer - occasionally I will use this tool (right-click a table, Design), but only at the beginning of projects, where I want to slightly adjust the column order in a new table.&amp;nbsp; Even in that case, more often than not, I'll drop and re-create the table.&amp;nbsp; For tables already in use, I always use DDL commands like ALTER TABLE, knowing that any new columns end up at the end of the table.&amp;nbsp; And that's okay with me.&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;/li&gt;&lt;li&gt;SQL Server Agent &amp;gt; Job History.&amp;nbsp; This dialog has some real quirkiness; in our environment, it is always confused because it is being run on a desktop in one time zone against servers in another.&amp;nbsp; I have been complaining about this since before SQL Server 2005 was released (though first officially documented in 2006; see &lt;a href="https://connect.microsoft.com/SQLServer/feedback/details/124841/very-odd-duration-listed-in-log-file-viewer" title="https://connect.microsoft.com/SQLServer/feedback/details/124841/very-odd-duration-listed-in-log-file-viewer" target="_blank"&gt;Connect #124841&lt;/a&gt;).&amp;nbsp; I also find the interface cumbersome to use and drill down - usually I get more complete and consumable information, and more immediately, from &lt;a href="http://www.sqlsentry.net/event-manager/sql-server-enterprise-overview.asp" title="http://www.sqlsentry.net/event-manager/sql-server-enterprise-overview.asp" target="_blank"&gt;SQL Sentry's Event Manager&lt;/a&gt; - which also has the ability to store more history in the repository without bogging down production instances of msdb.&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;Select Top N Rows.&amp;nbsp; This is a quick way to grab an arbitrary 1000 rows (or whatever number you customize) from a table.&amp;nbsp; Sadly, it just blindly executes the query without giving you the opportunity to modify the column list, where clause or isolation level (personally, I prefer Script &amp;gt; As SELECT To &amp;gt; New Query Editor Window).&amp;nbsp; Oh, and it won't necessarily put you in the context of the right database; instead, it uses a three-part name for the table, which can be frustrating if you try to add a simple join or subquery and forget which database you're really in.&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;&lt;b&gt;The "I will not touch it with a 10-foot pole"! variety:&lt;/b&gt;&lt;ul&gt;&lt;li&gt;Activity Monitor.&amp;nbsp; While this replacement of the useless view of the same name in previous iterations of the tool shows a lot of potential, and its 
motivation is in the right spot, it is in its infancy and has a lot of quirky behaviors.&amp;nbsp; If I want a good
 look at what is going on in my server, I will use &lt;a href="http://www.sqlsentry.net/performance-advisor/sql-server-performance-overview.asp" title="http://www.sqlsentry.net/performance-advisor/sql-server-performance-overview.asp" target="_blank"&gt;SQL
 Sentry's Performance Advisor&lt;/a&gt; - which does a great job of warning me about issues even when I'm not paying attention.&amp;nbsp; For a really quick pulse of current 
activity or in environments where I haven't convinced them to use 
Performance Advisor, then I turn to Adam Machanic's &lt;a href="http://sqlblog.com/files/folders/beta/entry26196.aspx" title="http://sqlblog.com/files/folders/beta/entry26196.aspx" target="_blank"&gt;sp_whoIsActive&lt;/a&gt;.&amp;nbsp; For a really quick look, yes, Activity Monitor can be useful... but for very little incremental effort you can get to a lot more information without memorizing all of the DMVs.&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;This will be ridiculously shocking, but any of the features that allow you to shrink a database or a file.&amp;nbsp; I acknowledge that there are some cases where shrinking a file is necessary, and I don't want to get into a religious battle about it.&amp;nbsp; I just wish that the task was much more difficult and thought-provoking to complete.&amp;nbsp; Rather than one button or checkbox, imagine if the process to shrink a file were as convoluted as setting up SQL Server?&amp;nbsp; There is one case where I'd applaud a longer and more cumbersome set of steps to accomplish a simple task.&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;/li&gt;&lt;li&gt;Most other designers / wizards.&amp;nbsp; Including, but not limited to:&lt;/li&gt;&lt;/ul&gt;&lt;blockquote&gt;&lt;ol&gt;&lt;li&gt;View Designer&lt;/li&gt;&lt;li&gt;Query Designer&lt;/li&gt;&lt;li&gt;Edit Top N Rows (formerly &lt;a href="https://connect.microsoft.com/SQLServer/feedback/details/264592/ssms-deprecate-open-table" title="https://connect.microsoft.com/SQLServer/feedback/details/264592/ssms-deprecate-open-table" target="_blank"&gt;Open Table&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;New/Edit Database&lt;/li&gt;&lt;li&gt;New/Edit Login&lt;br&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/blockquote&gt;&lt;blockquote&gt;Go ahead, search Connect.&amp;nbsp; There are dozens of bugs against these dialogs, and few if any will ever be fixed.&amp;nbsp; I can quote myself on twitter from earlier tonight: "Never send a UI to do a DDL's job."&amp;nbsp; As I've explained above, this isn't always true; but in most cases the DDL is going to be more predictable and also infinitely more repeatable.&lt;/blockquote&gt;&lt;p&gt;&lt;br&gt;&lt;b&gt;The "Wait, why isn't that feature there?" variety&lt;/b&gt;&lt;/p&gt;&lt;p&gt;I'm cheating here a little bit, but there are some noticeable omissions from Management Studio that I can't even complain about because they never bothered to create them.&amp;nbsp; UIs to support features that are cumbersome to set up using code alone, such as Service Broker and Extended Events (they are gradually getting to others such as Mirroring and of course the new DACPAC stuff).&amp;nbsp; Or things that are long overdue but are otherwise covered by great 3rd party add-ins, like Mladen Prajdic's &lt;a href="http://www.ssmstoolspack.com/" title="http://www.ssmstoolspack.com/" target="_blank"&gt;SSMS Tools Pack&lt;/a&gt;.&lt;br&gt;&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;b&gt;The "Oh yeah, I didn't even think of that one!" variety&lt;br&gt;&lt;/b&gt;&lt;br&gt;It is a pretty vast application and there are probably several features I didn't even think to mention.&amp;nbsp; So again, I'll ask: which parts of SSMS can you not live without?&amp;nbsp; Which ones would you throw off a pier if you were in control?&lt;br&gt;&lt;/p&gt;</description></item><item><title>Your work may not be lost</title><link>http://sqlblog.com/blogs/roman_rehak/archive/2010/01/28/your-work-may-not-be-lost.aspx</link><pubDate>Thu, 28 Jan 2010 15:22:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:21561</guid><dc:creator>roman</dc:creator><description>One of the things that I found dissapointing in Management Studio 2008 is that in the event of a crash (and in addition to&amp;nbsp;crashing in the first place), is that on&amp;nbsp;a restart it doesn't show me a dialog with a list of auto-saved files, like&amp;nbsp;my SSMS&amp;nbsp;2005 did. Yesterday as I was doing some houskeeping on my disk, I noticed a Backup folder under My Documents\SQL Server Managamnet Studio. I looked to see what's there and I saw a bunch of ~AutoRecover.~vs*.sql files, one for each query window in SSMS I was working with. This morning my SSMS crashed and when I reopened, there was no dialog for potential recovery. So I went to that folder and luckily, all the files were still there. I haven't searched Connect yet but I will, and&amp;nbsp;report this as a bug. If there are any files in that folder,&amp;nbsp;the user should be prompted with the option to recover.</description></item></channel></rss>