<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-6367058912647240061</atom:id><lastBuildDate>Sat, 14 Feb 2026 08:52:44 +0000</lastBuildDate><category>SQL Server 2008</category><category>T-SQL</category><category>Audit</category><category>Auditing</category><category>Change Data</category><category>Data Types</category><category>History</category><category>Mirror</category><category>Mirroring</category><category>SSMS</category><category>Tools</category><category>Tracking</category><category>Applications</category><category>Assignment</category><category>Automatic Failover</category><category>CDC</category><category>Change Data Capture</category><category>Change Tracking</category><category>Disaster Recovery</category><category>Encryption</category><category>Enhanced Events</category><category>High Availability</category><category>MERGE</category><category>Managment</category><category>Managment Studio</category><category>Non-Standard Clients</category><category>Principal</category><category>Row Constructors</category><category>Row Versioning</category><category>Security</category><category>Version</category><category>Witness</category><title>Slinging SQL</title><description>All topics SQL Server, from 2005 and on. Additional topics will include TFS, WIX, MSBuild and Powershell.</description><link>http://sqlslinger.blogspot.com/</link><managingEditor>noreply@blogger.com (Dan Ward)</managingEditor><generator>Blogger</generator><openSearch:totalResults>13</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6367058912647240061.post-8045657336754994437</guid><pubDate>Tue, 13 Apr 2010 17:33:00 +0000</pubDate><atom:updated>2010-04-13T13:35:50.538-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Applications</category><category domain="http://www.blogger.com/atom/ns#">Mirror</category><category domain="http://www.blogger.com/atom/ns#">Mirroring</category><category domain="http://www.blogger.com/atom/ns#">Non-Standard Clients</category><category domain="http://www.blogger.com/atom/ns#">SQL Server 2008</category><title>SharePoint on SQL Server Mirrors?!?!?!</title><description>&lt;p&gt;&lt;/p&gt;  &lt;p&gt;Yes, while SharePoint does not have the native ability to recognize a SQL Server 2008 Database Mirroring Session, you can configure it in such a way that you can protect your SharePoint installation with high availability for a lower cost. (It should be noted that SharePoint is recommended to run on a SQL Server cluster)&lt;/p&gt;  &lt;p&gt;&lt;/p&gt; I recently implemented SharePoint on SQL Mirrors for a client, and the following is the method which I chose to use. (Some images have been redacted)&amp;#160; &lt;h3&gt;&lt;a name=&quot;_Toc254869923&quot;&gt;Background&lt;/a&gt;&lt;/h3&gt;  &lt;p&gt;Setting up mirroring on SQL Server to be utilized by a SharePoint installation requires some additional steps to achieve automatic failover. SharePoint is not a mirroring aware product, it does not allow for capturing the FAILOVER PARTNER attribute for connection strings. In order to accomplish this you have a couple of options.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;First you can manually alter the connection string settings in the configuration files for SharePoint. As this is not the recommended or selected approach it will not be discussed, other than to state that the danger in this is any upgrade or service pack could cause configuration files to be overwritten and the addition of the FAILOVER PARTNER attribute in the connection strings could be lost.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;The selected method of running SharePoint against databases that are mirrored is described in detail below.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;As a starting point we used the Microsoft White Paper “Using SQL Server Mirroring with Office SharePoint Server® and Windows SharePoint Services®”. This document can be accessed via the link below.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;a title=&quot;Using Database Mirroring with Office SharePoint Server and Windows SharePoint Services&quot; href=&quot;http://go.microsoft.com/fwlink/?LinkId=83725&amp;amp;clcid=0x409&quot;&gt;Using Database Mirroring with Office SharePoint Server and Windows SharePoint Services&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;The white paper describes how to set up the mirroring, how to set up a SQL Alias for SharePoint to use as a data source, and how to set up SharePoint to use that SQL Alias. When the database mirroring session fails over to the mirror server, the SQL Alias on the SharePoint servers can be modified to point to the mirror server, which has become the principal server, thereby removing the need to reconfigure SharePoint. Because the above white paper does not provide a method for automating the failover from the principal database server to the mirror server, we had to derive how to do this on our own. Following is the detailed documentation of the steps involved in automating the switch over for SharePoint to use the alternate database server.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;h3&gt;&lt;a name=&quot;_Toc254869924&quot;&gt;Remotely updating the SQL Server Alias&lt;/a&gt;&lt;/h3&gt;  &lt;p&gt;The first step to achieving automated failover for SharePoint is to automate the update to the SQL Server Alias on each SharePoint Web Front End server and Application server. The SQL Alias configuration is held within the Windows Registry on each individual server, therefore a process must be run to update the value of the SQL Alias to change the Server attribute portion to match the currently active database principal. The registry value is held at HKLM\SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo\&amp;lt;SQL Alias Name&amp;gt;. &amp;lt;SQL Alias Name&amp;gt; is a REG_SZ key with a comma separated value that represents the connection type and server and if necessary the port number.&lt;/p&gt;  &lt;p style=&quot;width: 443px; height: 10.64%&quot;&gt;&lt;/p&gt;  &lt;p&gt;We created A pair of batch files to reside on each server. The pair of batch consists of one file for each database server in the mirroring session. For development we have chosen to place the files within a folder named “SQLServerMirrorScripts” on the root of drive C:. Note, we could have chosen different options for this, such as PowerShell scripts but due to client standards and preference we were limited.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Note the content of one of the batch files: &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot;&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;set DBSERVERALIAS=SQLAlias&lt;/p&gt;          &lt;p&gt;set DBSERVER=DBSrv2&lt;/p&gt;          &lt;p&gt;reg add HKLM\Software\Microsoft\MSSQLServer\Client\ConnectTo /v %DBSERVERALIAS% /t REG_SZ /d &amp;quot;DBMSSOCN,%DBSERVER%&amp;quot; /f&lt;/p&gt;          &lt;p&gt;reg query HKLM\Software\Microsoft\MSSQLServer\Client\ConnectTo&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;The next step is to find a way to execute the batch files from a remote server, the database servers, but within the process space of the target server, the MOSS servers. In order to accomplish this we are used a utility called psexec.exe. You can attain this utility from Microsoft at &lt;a href=&quot;http://technet.microsoft.com/en-us/sysinternals/bb897553.aspx&quot; target=&quot;_blank&quot;&gt;Microsoft PSTools Page&lt;/a&gt;. This utility is a DOS based program that will remotely execute a process on a server under the currently logged in user context or under the user provided by command line argument. Each database server has another pair of batch files that encapsulate the execution command for the appropriate SQL Alias editing batch file on the remote server. These files, along with the psexec utility executable reside on each database server in a folder called “SQLServerMirrorScripts” in the root of drive C:&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Again, each batch file is named for the database server it is going to change the SQL Alias too. Each batch file executes the remote batch file appropriate, designated in its name, to the operation. Below is the content of these batch files. These files exist in the same location on each of the database servers.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot;&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;C:\SQLServerMirrorScripts\psexec.exe &lt;a href=&quot;file://\\SharePointServer&quot;&gt;\\SharePointServer&lt;/a&gt; C:\SQLServerMirrorScripts\SQLAlias1.bat -d -e&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;At this point we have a process that will allow us to change the SQL Server Alias value from a remote location. &lt;b&gt;When using psexec.exe for the first time from a server, you must manually execute the application and accept the license agreement that will popup. If this step is skipped the process will fail, because it will always wait for license acceptance.&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;h3&gt;&lt;a name=&quot;_Toc254869925&quot;&gt;Automating the SQL Server Alias Update&lt;/a&gt;&lt;/h3&gt;  &lt;p&gt;While the previous steps will allow us to modify the SQL Server Alias from each database server, they do not provide for the automatic updating of the alias in response to a database failing over from the principal server to the mirror server. In order to accomplish the automation, several additional steps are required.&lt;/p&gt;  &lt;h4&gt;&lt;a name=&quot;_Toc254869926&quot;&gt;Enabling Service Broker for each database&lt;/a&gt;&lt;/h4&gt;  &lt;p&gt;In order to enable automation, there must be a mechanism in place to respond to an event. In order to provide event notification in SQL Server, Service Broker must be enabled for all the mirrored databases and the msdb database. If you are unsure if Service Broker is enabled for your database you can execute the following query to find out.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; width=&quot;423&quot;&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td width=&quot;421&quot;&gt;         &lt;p&gt;USE master&lt;/p&gt;          &lt;p&gt;Go&lt;/p&gt;          &lt;p&gt;SELECT name, is_broker_enabled &lt;/p&gt;          &lt;p&gt;FROM sys.databases&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;This will list the databases and a binary value for the state of is_broker_enabled, 0 is no, and 1 is yes.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt; &lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDBWpt6XexDEOTjqn6as8YIQc8HEf7ZoJ53MlEVitlGHm_nIvs41Ti3fprBKpklYlscZVpBq5yBKJq5HvrtbU2hTm-PQdGXoLeZb3AvWEQ-Cab3DK8Xjx6d4MO4Nfmx94F0mI2564o_po/s1600-h/image%5B7%5D.png&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqa08e4tc7xaDU0p1-TTzH11Pe4GnX8cXKmdq9qdgebdLkGhheZQFl7pkQrQ-4iBJkMixO2sa0LvqFGjUuhUVxtJJQ1zbsgiEhdt2sXbuZ7XeDWvaP8sCmpD8e0aThfrMqR7ePdnz9I5M/?imgmax=800&quot; width=&quot;427&quot; height=&quot;166&quot; /&gt;&lt;/a&gt;   &lt;p&gt;&lt;/p&gt;  &lt;p&gt;By default, SharePoint databases are created with Service Broker enabled, but if there is a need to enable it after the database is created, the following command can be issued in SQL Server Management Studio;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; width=&quot;423&quot;&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td width=&quot;421&quot;&gt;         &lt;p&gt;ALTER DATABASE &amp;lt;DATABASE NAME&amp;gt; SET ENABLE_BROKER&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;You must also ensure that SQL Server Agent is running. If it is not, you must start the service, either via the services control snap in    &lt;br /&gt;&lt;/p&gt; &lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiq7pYmUXfpknyuyr4jny6H3Rtjq0Kte7Q1ZAmnqqhKw7BdExSPAzP3jE0LPfr8l2eNAeWbn9jvtkjjDaUNnht0QgV-b2UZ9kYfS0pzY6GZ_vy0Q393iVkaFnaZINg0eoe9Ug8YjQlEQR0/s1600-h/image%5B11%5D.png&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4KjlwkltRrtB4VNKZQvOwB1qTUkQ88XZ_rvYD013ztkFFQjF_g7DNZDrfY4klx9cQJfI48Grq2ToHQTMw_P6oWRREWbGDDywRsO15QN46aEHxSNjDSWxf4u2NM4bn7BMQtiB1M9Be11k/?imgmax=800&quot; width=&quot;433&quot; height=&quot;308&quot; /&gt;&lt;/a&gt;   &lt;p&gt;or command line.    &lt;br /&gt;&lt;/p&gt;  &lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; width=&quot;432&quot;&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td width=&quot;430&quot;&gt;         &lt;p&gt;net start SQLSERVERAGENT&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;br /&gt;  &lt;h4&gt;&lt;a name=&quot;_Toc254869927&quot;&gt;Setting Up the Event Notification&lt;/a&gt;&lt;/h4&gt;  &lt;p&gt;DATABASE_MIRRORING_STATE_CHANGE is not one of the events that can be automatically trapped. The event is available as a manually created Event Notification.    &lt;br /&gt;You will need to create an event notification named DBMirrorStateChange to raise a notification for the DATABASE_MIRRORING_STATE_CHANGE event, on both database servers in the mirroring session (not the witness):&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot;&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;If Not Exists (Select 1 From sys.server_event_notifications Where name = &#39;DBMirrorStateChange&#39;)&lt;/p&gt;          &lt;p&gt;Begin&lt;/p&gt;          &lt;p&gt;Create Event Notification DBMirrorStateChange&lt;/p&gt;          &lt;p&gt;On Server&lt;/p&gt;          &lt;p&gt;For DATABASE_MIRRORING_STATE_CHANGE&lt;/p&gt;          &lt;p&gt;To Service &#39;DBMirrorService&#39;, &#39;current database&#39;;&lt;/p&gt;          &lt;p&gt;End&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;This code need only be execute for a single database, denoted above as ‘current database’, in order to create the event notification that will be used for any database the has a mirroring state change.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;If it ever becomes necessary to remove an event notification you can use the code below;&lt;/p&gt;  &lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot;&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td width=&quot;84&quot;&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;&lt;/td&gt;        &lt;td width=&quot;634&quot;&gt;         &lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; width=&quot;447&quot;&gt;&lt;tbody&gt;             &lt;tr&gt;               &lt;td width=&quot;445&quot;&gt;                 &lt;p&gt;DROP EVENT NOTIFICATION notification_name [,...n ]&lt;/p&gt;                  &lt;p&gt;ON { SERVER | DATABASE | QUEUE queue }[;]&lt;/p&gt;               &lt;/td&gt;             &lt;/tr&gt;           &lt;/tbody&gt;&lt;/table&gt;          &lt;p&gt;&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;p&gt;The DATABASE_MIRRORING_STATE_CHANGE event notification provides a property that denotes what type of state change has happened. This “state” property will inform us of what type of state change has occurred. The possible states for the event are as follows;&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;table border=&quot;1&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; width=&quot;445&quot;&gt;&lt;tbody&gt;             &lt;tr&gt;               &lt;td valign=&quot;bottom&quot;&gt;                 &lt;p&gt;&lt;b&gt;State&lt;/b&gt;&lt;/p&gt;               &lt;/td&gt;                &lt;td valign=&quot;bottom&quot; width=&quot;154&quot;&gt;                 &lt;p&gt;&lt;b&gt;Name&lt;/b&gt;&lt;/p&gt;               &lt;/td&gt;                &lt;td valign=&quot;bottom&quot; width=&quot;252&quot;&gt;                 &lt;p&gt;&lt;b&gt;Description&lt;/b&gt;&lt;/p&gt;               &lt;/td&gt;             &lt;/tr&gt;              &lt;tr&gt;               &lt;td valign=&quot;top&quot;&gt;                 &lt;p&gt;0&lt;/p&gt;               &lt;/td&gt;                &lt;td valign=&quot;top&quot; width=&quot;154&quot;&gt;                 &lt;p&gt;Null Notification&lt;/p&gt;               &lt;/td&gt;                &lt;td valign=&quot;top&quot; width=&quot;252&quot;&gt;                 &lt;p&gt;This state occurs briefly when a mirroring session is started.&lt;/p&gt;               &lt;/td&gt;             &lt;/tr&gt;              &lt;tr&gt;               &lt;td valign=&quot;top&quot;&gt;                 &lt;p&gt;1&lt;/p&gt;               &lt;/td&gt;                &lt;td valign=&quot;top&quot; width=&quot;154&quot;&gt;                 &lt;p&gt;Synchronized Principal with Witness&lt;/p&gt;               &lt;/td&gt;                &lt;td valign=&quot;top&quot; width=&quot;252&quot;&gt;                 &lt;p&gt;This state occurs on the principal when the principal and mirror are connected and synchronized and the principal and witness are connected. For a mirroring configuration with a witness, this is the normal operating state.&lt;/p&gt;               &lt;/td&gt;             &lt;/tr&gt;              &lt;tr&gt;               &lt;td valign=&quot;top&quot;&gt;                 &lt;p&gt;2&lt;/p&gt;               &lt;/td&gt;                &lt;td valign=&quot;top&quot; width=&quot;154&quot;&gt;                 &lt;p&gt;Synchronized Principal without Witness&lt;/p&gt;               &lt;/td&gt;                &lt;td valign=&quot;top&quot; width=&quot;252&quot;&gt;                 &lt;p&gt;This state occurs on the principal when the principal and mirror are connected and synchronized but the principal does not have a connection to the witness. For a mirroring configuration without a witness, this is the normal operating state.&lt;/p&gt;               &lt;/td&gt;             &lt;/tr&gt;              &lt;tr&gt;               &lt;td valign=&quot;top&quot;&gt;                 &lt;p&gt;3&lt;/p&gt;               &lt;/td&gt;                &lt;td valign=&quot;top&quot; width=&quot;154&quot;&gt;                 &lt;p&gt;Synchronized Mirror with Witness&lt;/p&gt;               &lt;/td&gt;                &lt;td valign=&quot;top&quot; width=&quot;252&quot;&gt;                 &lt;p&gt;This state occurs on the mirror when the principal and mirror are connected and synchronized and the mirror and witness are connected. For a mirroring configuration with a witness, this is the normal operating state.&lt;/p&gt;               &lt;/td&gt;             &lt;/tr&gt;              &lt;tr&gt;               &lt;td valign=&quot;top&quot;&gt;                 &lt;p&gt;4&lt;/p&gt;               &lt;/td&gt;                &lt;td valign=&quot;top&quot; width=&quot;154&quot;&gt;                 &lt;p&gt;Synchronized Mirror without Witness&lt;/p&gt;               &lt;/td&gt;                &lt;td valign=&quot;top&quot; width=&quot;252&quot;&gt;                 &lt;p&gt;This state occurs on the mirror when the principal and mirror are connected and synchronized but the mirror does not have a connection to the witness. For a mirroring configuration without a witness, this is the normal operating state.&lt;/p&gt;               &lt;/td&gt;             &lt;/tr&gt;              &lt;tr&gt;               &lt;td valign=&quot;top&quot;&gt;                 &lt;p&gt;5&lt;/p&gt;               &lt;/td&gt;                &lt;td valign=&quot;top&quot; width=&quot;154&quot;&gt;                 &lt;p&gt;Connection with Principal Lost&lt;/p&gt;               &lt;/td&gt;                &lt;td valign=&quot;top&quot; width=&quot;252&quot;&gt;                 &lt;p&gt;This state occurs on the mirror server instance when it cannot connect to the principal.&lt;/p&gt;               &lt;/td&gt;             &lt;/tr&gt;              &lt;tr&gt;               &lt;td valign=&quot;top&quot;&gt;                 &lt;p&gt;6&lt;/p&gt;               &lt;/td&gt;                &lt;td valign=&quot;top&quot; width=&quot;154&quot;&gt;                 &lt;p&gt;Connection with Mirror Lost&lt;/p&gt;               &lt;/td&gt;                &lt;td valign=&quot;top&quot; width=&quot;252&quot;&gt;                 &lt;p&gt;This state occurs on the principal server instance when it cannot connect to the mirror.&lt;/p&gt;               &lt;/td&gt;             &lt;/tr&gt;              &lt;tr&gt;               &lt;td valign=&quot;top&quot;&gt;                 &lt;p&gt;7&lt;/p&gt;               &lt;/td&gt;                &lt;td valign=&quot;top&quot; width=&quot;154&quot;&gt;                 &lt;p&gt;Manual Failover&lt;/p&gt;               &lt;/td&gt;                &lt;td valign=&quot;top&quot; width=&quot;252&quot;&gt;                 &lt;p&gt;This state occurs on the principal server instance when the user fails over manually from the principal, or on the mirror server instance when a force service is executed at the mirror.&lt;/p&gt;               &lt;/td&gt;             &lt;/tr&gt;              &lt;tr&gt;               &lt;td valign=&quot;top&quot;&gt;                 &lt;p&gt;8&lt;/p&gt;               &lt;/td&gt;                &lt;td valign=&quot;top&quot; width=&quot;154&quot;&gt;                 &lt;p&gt;Automatic Failover&lt;/p&gt;               &lt;/td&gt;                &lt;td valign=&quot;top&quot; width=&quot;252&quot;&gt;                 &lt;p&gt;This state occurs on the mirror server instance when the operating mode is high safety with automatic failover (synchronous) and the mirror and witness server instances cannot connect to the principal server instance.&lt;/p&gt;               &lt;/td&gt;             &lt;/tr&gt;              &lt;tr&gt;               &lt;td valign=&quot;top&quot;&gt;                 &lt;p&gt;9&lt;/p&gt;               &lt;/td&gt;                &lt;td valign=&quot;top&quot; width=&quot;154&quot;&gt;                 &lt;p&gt;Mirroring Suspended&lt;/p&gt;               &lt;/td&gt;                &lt;td valign=&quot;top&quot; width=&quot;252&quot;&gt;                 &lt;p&gt;This state occurs on both partner instances when the user suspends (pauses) the mirroring session or when the mirror server instance encounters an error. It also occurs on the mirror server instance following a force service command. When the mirror comes online as the principal, mirroring is automatically suspended.&lt;/p&gt;               &lt;/td&gt;             &lt;/tr&gt;              &lt;tr&gt;               &lt;td valign=&quot;top&quot;&gt;                 &lt;p&gt;10&lt;/p&gt;               &lt;/td&gt;                &lt;td valign=&quot;top&quot; width=&quot;154&quot;&gt;                 &lt;p&gt;No Quorum&lt;/p&gt;               &lt;/td&gt;                &lt;td valign=&quot;top&quot; width=&quot;252&quot;&gt;                 &lt;p&gt;If a witness is configured, this state occurs on the principal or mirror server instance when it cannot connect to its partner or to the witness server instance.&lt;/p&gt;               &lt;/td&gt;             &lt;/tr&gt;              &lt;tr&gt;               &lt;td valign=&quot;top&quot;&gt;                 &lt;p&gt;11&lt;/p&gt;               &lt;/td&gt;                &lt;td valign=&quot;top&quot; width=&quot;154&quot;&gt;                 &lt;p&gt;Synchronizing Mirror&lt;/p&gt;               &lt;/td&gt;                &lt;td valign=&quot;top&quot; width=&quot;252&quot;&gt;                 &lt;p&gt;This state occurs on the mirror server instance when there is a backlog of unsent log. The status of the session is Synchronizing.&lt;/p&gt;               &lt;/td&gt;             &lt;/tr&gt;              &lt;tr&gt;               &lt;td valign=&quot;top&quot;&gt;                 &lt;p&gt;12&lt;/p&gt;               &lt;/td&gt;                &lt;td valign=&quot;top&quot; width=&quot;154&quot;&gt;                 &lt;p&gt;Principal Running Exposed&lt;/p&gt;               &lt;/td&gt;                &lt;td valign=&quot;top&quot; width=&quot;252&quot;&gt;                 &lt;p&gt;This state occurs on the principal server instance when the operating mode is high protection (synchronous) and the principal cannot connect to the mirror server instance.&lt;/p&gt;               &lt;/td&gt;             &lt;/tr&gt;              &lt;tr&gt;               &lt;td valign=&quot;top&quot;&gt;                 &lt;p&gt;13&lt;/p&gt;               &lt;/td&gt;                &lt;td valign=&quot;top&quot; width=&quot;154&quot;&gt;                 &lt;p&gt;Synchronizing Principal&lt;/p&gt;               &lt;/td&gt;                &lt;td valign=&quot;top&quot; width=&quot;252&quot;&gt;                 &lt;p&gt;This state occurs on the principal server instance when there is a backlog of unsent log. The status of the session is Synchronizing.&lt;/p&gt;               &lt;/td&gt;             &lt;/tr&gt;           &lt;/tbody&gt;&lt;/table&gt;          &lt;h4&gt;&lt;a name=&quot;_Toc254869928&quot;&gt;Creating an Alert for Automatic Failover capture&lt;/a&gt;&lt;/h4&gt;          &lt;p&gt;We are interested in State 8 for this step. State 8 indicates an automatic fail over has occurred. This event is raised on the mirror server when a database that is acting as the mirror, changes state to acting as the principal.&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;p&gt;The mechanism we use for responding to an event notification is an alert. An alert can be created via SQL Server Management Studio (SSMS), or via T-SQL script. The SSMS method will be shown here. Locate and expand the SQL Server Agent node in the SSMS object tree view.&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoJpqfq-SsByQ0xLOdp37coEQl_TUeJajNnJOx3JTXzWjLL91ZDG_GPoB8Qa97uWuF1qQ0_CpWRzAHKOk8BP4mCWhIHUv8e4rQcfEZOhXmzf7ZS3-okl5wVb3p30hVp8-mFpEQnNzFgOo/s1600-h/image%5B15%5D.png&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDZFv8cUw1hyphenhyphenYYFpWIFKrI7dR7L5ca3oBAXsu0suGBJH8mhtRV8NXGpqNrMp511omJnQhRWDFTfU8vYXzWYQ_nkSwmkCQgbI6tevDWQr7Jp3X91IVfGD98_Up2NL8WrfYlTy1Qg6hyphenhyphen3Uk/?imgmax=800&quot; width=&quot;248&quot; height=&quot;169&quot; /&gt;&lt;/a&gt; &lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;p&gt;Right click on Alerts and select “New Alert”. Enter a name for the Alert in the Name: attribute box, select WMI event alert in the Type drop down list. The Namespace: value will be populated automatically for the server you are on. Note: you will have to do this on both servers, but you can script the alerts and jobs from the first server and use those scripts on the second server as shown later. In the Query: box you will write the query based on the DATABASE_MIRRORING_STATE_CHANGE event.&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCdEMwud_zjZlO0934V0ncFOffDNSQqGNFarTR2lDlyUbAMhWWP2Pz44NOQVb3hgcIaVPtJ3v527LpaeR7bHrynaVcr-lwmBJ9Heo6Gd5xv1gIVf8wdZGFE_kvEmL04jJFPkgUztHlCik/s1600-h/DB_MIRROR_ALERT1_redact%5B4%5D.png&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; title=&quot;DB_MIRROR_ALERT1_redact&quot; border=&quot;0&quot; alt=&quot;DB_MIRROR_ALERT1_redact&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVJ0rjBLToHFOTlkJD3ECEsYjzkzjB3Sq3OhB-HwtF5Px_hSURuOyPkc48sQQL_haNLEi8HTiaeu8wPfN5dWkjLgbqkzx0ZKMRHDSSFyIjy73nn26Ie7GPZYgJegeU6gqe3v1H5mPq880/?imgmax=800&quot; width=&quot;441&quot; height=&quot;394&quot; /&gt;&lt;/a&gt;&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;p&gt;Select the Response page and check the box for “Execute Job”, then select the “New Job” button.&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinaGHe0JwfFi7gA0ukxRjuRtQphdKpVKZDbgtUkibbsIJZHCPqOvnq4ZjFOLqXY1ltX7OyEgYImXdqrYSpP1gRfQPqiZt49iNa0eYWde3bxaZN-2FNSeaj5stRaM9mhiAoLPcIjNO78Iw/s1600-h/DB_MIRROR_ALERT2_redact%5B3%5D.png&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; title=&quot;DB_MIRROR_ALERT2_redact&quot; border=&quot;0&quot; alt=&quot;DB_MIRROR_ALERT2_redact&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhu-KQX7gBA1mgpuUyhRjzuz0W6mBtQVaEFq5KpLCTZWl9smGDvn5UWysaD0qR23hFeHspEj9xu5FboCiZ0qYQ-nzrMPYD51iMJ7xjse7rdWyJfbGdxI2XCMNRPP-DG6aVHYOlXh6YpreA/?imgmax=800&quot; width=&quot;446&quot; height=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;p&gt;This will create a new job and open the Job properties dialog for you. Enter a job name, owner and select the category as Database Mirroring. If the category “Database Mirroring” is not available select “Uncategorized (Local)”. Enter a description to detail the purpose of the job, and ensure Enabled is checked.&lt;/p&gt;          &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyKyWkrLut0_mpgW8lKwWiPk9kq8EewnoR64uil4MTxVhbiWELWeboQXm7V9MmeuANnSutntDj3oBYaXUy6-QxyH_KxRwSJLbBFzbu8vjQPJPo7igKYwWML-SBviyPq4J3wDV2T3PT5ek/s1600-h/DB_MIRROR_JOB1_redact%5B3%5D.png&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; title=&quot;DB_MIRROR_JOB1_redact&quot; border=&quot;0&quot; alt=&quot;DB_MIRROR_JOB1_redact&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqWvMEEcgdotRs9xI9l-uo5kFB6SngrImC205O9-A3eDRqj253I3HgymGr0PwXvFeJ-oavTEpNIgDdxO2orXMUL3HS6yOGTyGqj2pBwUMatmhbF0wCHcJo9yMXFGki6sTQjY6LFQwIEr4/?imgmax=800&quot; width=&quot;441&quot; height=&quot;394&quot; /&gt;&lt;/a&gt;&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;p&gt;Select the Steps page on the left next. And select the “New” Button on the bottom. This will launch the Job Step properties page.&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;p&gt;Enter a name for the job step you are creating, select the type, in this case we are executing a batch file so select “Operating System (CmdExec)”, and chose the Run As account from the drop down. This will be the user that the process will run under. In the Command box input the batch file for the server you are working on and click “OK”.&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0PbMb2q_wjyDQFnz2JlSoKZH0lVVjqx0UHlPvG3HZTNNNWErqK_y53Fz-6ddpG2B88FssEQaigFj5JV7cEYyzZB5Xs4jmciWe4DRLaTLuEeSxV5FKKdH5ZdXSwqaqG1lqP0e7Vy2uUz4/s1600-h/DB_MIRROR_JOB3_redact%5B3%5D.png&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; title=&quot;DB_MIRROR_JOB3_redact&quot; border=&quot;0&quot; alt=&quot;DB_MIRROR_JOB3_redact&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3AeI8LcjqiHtTnPqbATJ5x6OwO7_WG3l2vy_TEKzDeSZ4LG6BDcmQWqN4eg_TTZkrjq9iNrQgoizlXa0M61iwRJLNRxitT4pyJufQ4aZD9NP0PNRZVCGNRWKFJpDwAPYQz6OU5jP-WFc/?imgmax=800&quot; width=&quot;453&quot; height=&quot;408&quot; /&gt;&lt;/a&gt;&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;p&gt;Back on the Alert properties page now, click “OK” to finish creating the Alert.&lt;/p&gt;          &lt;p&gt;We now have an Alert that will capture the event that a database has gone from Mirror to Principal and take appropriate action. When the event occurs, the Alert is activated if the state value is 8. The Alert then executes the Job that was created, and the job executes the batch file which executes the psexec utility to execute the batch file on the SharePoint server, which modifies the registry to change the server value for the SQL Server Alias.&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;h4&gt;&lt;a name=&quot;_Toc254869929&quot;&gt;Creating an Alert for Manual Failover capture&lt;/a&gt;&lt;/h4&gt;          &lt;p&gt;A manual fail over is different than an automatic fail over, in that it fires an event with state 7 that occurs on the Principal server where the fail over command originated. Because SharePoint is a multi-database application, it is desired that all databases reside on the same server at all times. For automatic fail overs, it would be rare that the fail over would happen at a database level. Normally it will occur because the server went down, the network card failed, the disks failed, or some other catastrophic event occurred which rendered the Principal server inoperable. Manual fail over occurs when the Fail Over button is pressed in the Mirroring properties of the database or when certain T-SQL commands are issued. Manual fail over occurs at the database level, therefore a mechanism to automate manual fail over for the SharePoint instance, must not only change the SQL Server Alias, but also cause the other SharePoint databases to fail over to the Mirror. We will follow the same steps as for Automatic fail over, but we will add a new step to the job before the alias update step.&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;p&gt;Locate and expand the SQL Server Agent node in the SSMS object tree view.&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPK2qAyTyNfYS2Ae4Ww4TQbFD1N1Hhwn4ndwYDSCiQUsY_hWT34NjGlCJ9J46nblsQNu_7xMlGo_98ahyLKEWSiZQ6jFBuz8gAqg2v0Yy_fPAyZVksYLT9QtUOHvEmNAVAn7_UI__uuAI/s1600-h/image%5B19%5D.png&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjA456XLLofv5RKHWxNC76u8zaaywiNv7ZAYajmNiSOGLfhV7kcXN7ihH2quy3PLqX4U446cpkdHZJq-gZ1SMwC4jm1-5KLjaIwr6UaSLMOMHE5FbtK4nNbnZ9TiE8R8V1-TjwwL3JVDSE/?imgmax=800&quot; width=&quot;230&quot; height=&quot;157&quot; /&gt;&lt;/a&gt;&lt;/p&gt;          &lt;p&gt;&amp;#160;&lt;/p&gt;          &lt;p&gt;Right click on Alerts and select “New Alert”. Enter a name for the Alert in the Name: attribute box, select WMI event alert in the Type drop down list. The Namespace: value will be populated automatically for the server you are on. Note: you will have to do this on both servers, but you can script the alerts and jobs from the first server and use those scripts on the second server as &lt;b&gt;shown&lt;/b&gt; later. In the Query: box you will write the query based on the DATABASE_MIRRORING_STATE_CHANGE event. Note that we are looking for State 7 in this event response.&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSY64ElvW6IgCQ7_8DYw4UgCyu45du3auH6q-IcVX_aYQHI_1172ozE8UrDmW0UK-tnk8Rj3FzAkETYAzxVts0zf8wXRPf3zNkMLNs-mubCASvo81ZwtjTdYtV6KDmiP4TOKuogbAt-fs/s1600-h/DB_MIRROR_ALERT3_redact%5B7%5D.png&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; title=&quot;DB_MIRROR_ALERT3_redact&quot; border=&quot;0&quot; alt=&quot;DB_MIRROR_ALERT3_redact&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9Oe9uU9BiTVlxKTUv9aq24QGXGPxfyhvWAFuqUh47deWVvOXtKfyUtvqpK7WuGZ0hRljPjOSb2_2UuiEt1vEySeLeQCXcnksMxC4L5kvxw6omKcZ21H_ovtJeIdFrcLsNkzUzIh2Rn98/?imgmax=800&quot; width=&quot;453&quot; height=&quot;406&quot; /&gt;&lt;/a&gt;&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;p&gt;Select the Response page and check the box for “Execute Job”, then select the “New Job” button.&lt;/p&gt;          &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvg54UVFoau7v0TpMlJu-_6eKE8O2KiQg8hPfCrJ2HGfD9OhuCi1yNv9wTykvcN_dHeoBuMOhE1BxqGZbK_fAGJXIbi0x2GxDmB1N3SuSvxFsxH4DgnUzHIsPK_cosekhiSNtgcjkeJIw/s1600-h/DB_MIRROR_ALERT4_redact%5B3%5D.png&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; title=&quot;DB_MIRROR_ALERT4_redact&quot; border=&quot;0&quot; alt=&quot;DB_MIRROR_ALERT4_redact&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0ydEzOFhlIfkwTO9dL6SFfShk0c0NR7iZK8QAJaLvjKHocvW3_CH8GB9WiiCPHNQXquVE9XcWsrykjwvej2RaGSxK2F1JnDE_NM83YRoo-C6SRjoCW5ODi4MSZ3x3wM-40QWTDoeNYtQ/?imgmax=800&quot; width=&quot;453&quot; height=&quot;408&quot; /&gt;&lt;/a&gt;&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;p&gt;This will create a new job and open the Job properties dialog for you. Enter a job name, owner and select the category as Database Mirroring. If the category “Database Mirroring” is not available select “Uncategorized (Local)”. Enter a description to detail the purpose of the job, and ensure Enabled is checked.&lt;/p&gt;          &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHoPcN_6zXLCwhD-7g4iQ7bQb7jrRdNBXoqgXwAt25IL71u2QcbjUCZ0B8uK6uDwIDKhTVOPjzlPdRu61QgJiEM_4gBjB28f0YPyW1WOMm-rSWxuAjhjQsHq6_kksUZ3UdQPLED_PGPOc/s1600-h/DB_MIRROR_JOB4_redact%5B3%5D.png&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; title=&quot;DB_MIRROR_JOB4_redact&quot; border=&quot;0&quot; alt=&quot;DB_MIRROR_JOB4_redact&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhe5IMKSHGFBwkIN2E2xBSTv-aXwzPChTBg7bPInSkdnWzmPEVugiN0jqfTVVFCfJb6z3bwM-ArnwTy-2cXvm8pUvMcPYyDj6QI7ngnEU6zpUsYo_f2PQeIr08t0k3DVhCO-U2wz5EOU_Q/?imgmax=800&quot; width=&quot;452&quot; height=&quot;405&quot; /&gt;&lt;/a&gt;&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;p&gt;Select the Steps page on the left next. And select the “New” Button on the bottom. This will launch the Job Step properties page.&lt;/p&gt;         &lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgN8-knC1g1j-kXPlc3uUfiDR69hanqPRncd52uZzkLNbbr_GdfzhyphenhyphenUxyUAF3e_dFkLXFLSx62UQu65U1XE84B6vtAM-GGJmN0K0Zo2iAKByvpL46-3A6DBPAf2_c8Sf-Q_L5nZwgc6tpE/s1600-h/DB_MIRROR_JOB5_redact%5B3%5D.png&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; title=&quot;DB_MIRROR_JOB5_redact&quot; border=&quot;0&quot; alt=&quot;DB_MIRROR_JOB5_redact&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5P-yRB2eKlOusN8HL5PPgbokFR_CK67EkY46jPWIvICLE724Q3grgmzXzM1kfW9wgn-VrHByoma7qG2BWhkt_RvrDgzy6In9mIyKcTB7vbEp80qLDHJbVxgXcsBLjSVbtzZAKyYNBSxE/?imgmax=800&quot; width=&quot;455&quot; height=&quot;410&quot; /&gt;&lt;/a&gt;           &lt;p&gt;&lt;/p&gt;          &lt;p&gt;Enter a name for the job step you are creating, select the type, in this case we are a SQL Server query so select “Transact-SQL script (T-SQL)”. Leave the “Run As” box empty. In the Command box input the code shown and click “OK”.&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7BzJPqslSeI3vZaLJjap7grMn6bRdrVEBCipqQaWl-xXS57GgmzABdC02smygXUf95OlV9edES5JhswgIfP69OY3OvOOMPexho9CXjFOKSJHM8yA2pLwPVC-zkdW0_FVORqjuUh3UEVM/s1600-h/DB_MIRROR_JOB6_redact%5B3%5D.png&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; title=&quot;DB_MIRROR_JOB6_redact&quot; border=&quot;0&quot; alt=&quot;DB_MIRROR_JOB6_redact&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6FD_bTnz823WJC6PQrr_8VvHXK5xbkM7UncIGealovtwIr-uu2xsVgaM1y6DnPPIWsl0b4Yausgzdfrujelzm2o3NF1TKsv0vikykH9gQF_7w3NreUhIDMDYx49P99WeaWDasHi229QU/?imgmax=800&quot; width=&quot;456&quot; height=&quot;386&quot; /&gt;&lt;/a&gt;&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;         &lt;em&gt;Code from above step:&lt;/em&gt;           &lt;p&gt;&lt;/p&gt;          &lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot;&gt;&lt;tbody&gt;             &lt;tr&gt;               &lt;td&gt;                 &lt;p&gt;SET NOCOUNT OFF&lt;/p&gt;                  &lt;p&gt;DECLARE @strSQL NVARCHAR(4000)&lt;/p&gt;                  &lt;p&gt;DECLARE @strDatabasename NVARCHAR(2000)&lt;/p&gt;                  &lt;p&gt;DECLARE MyCursor CURSOR FOR&lt;/p&gt;                  &lt;p&gt;SELECT name FROM master.sys.databases a&lt;/p&gt;                  &lt;p&gt;INNER JOIN master.sys.database_mirroring b&lt;/p&gt;                  &lt;p&gt;ON a.database_id=b.database_id&lt;/p&gt;                  &lt;p&gt;WHERE NOT mirroring_guid IS NULL&lt;/p&gt;                  &lt;p&gt;AND mirroring_role_desc=&#39;PRINCIPAL&#39;&lt;/p&gt;                  &lt;p&gt;OPEN MyCursor&lt;/p&gt;                  &lt;p&gt;FETCH Next FROM MyCursor INTO @strDatabasename&lt;/p&gt;                  &lt;p&gt;WHILE @@Fetch_Status = 0&lt;/p&gt;                  &lt;p&gt;BEGIN&lt;/p&gt;                  &lt;p&gt;SET @strSQL = &#39;ALTER DATABASE [&#39; + @strDatabaseName + &#39;] SET PARTNER FAILOVER&#39;&lt;/p&gt;                  &lt;p&gt;EXEC sp_executesql @strSQL&lt;/p&gt;                  &lt;p&gt;FETCH Next FROM MyCursor INTO @strDatabasename&lt;/p&gt;                  &lt;p&gt;END&lt;/p&gt;                  &lt;p&gt;CLOSE MyCursor&lt;/p&gt;                  &lt;p&gt;DEALLOCATE MyCursor&lt;/p&gt;               &lt;/td&gt;             &lt;/tr&gt;           &lt;/tbody&gt;&lt;/table&gt;          &lt;p&gt;&lt;/p&gt;          &lt;p&gt;This code will force all databases on the server to become the “FailOver Partner” or Mirror, which causes the existing Mirror, or “FailOver Partner” to become the principal.&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;p&gt;Back on the Job properties Steps page now, click “New” to create another step. This step will be identical to the job step for automatic failover, with the exception of which batch file it calls. Enter the values as below and click “Ok”.&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_7oTiznMLiW9w_u_-WKfJ4-jY1BlRNrKzXq-68BgGl1VZfMrubHM3Vo4S2M5Cr8EVgTCYRVnsAbqRHeT-6LZwWrPqGLat131Up33oLlEmhtWzWyI-wbFearh5T4iWEDbCKTiJwHRVEpk/s1600-h/DB_MIRROR_JOB3_redact%5B7%5D.png&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; title=&quot;DB_MIRROR_JOB3_redact&quot; border=&quot;0&quot; alt=&quot;DB_MIRROR_JOB3_redact&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7ZqY9Mh2_HzH1mCN8JEgvFEjTRdQgKZ2tblwcb65aSN7vy6YjyK6wmJWGVhnQJkb2fwQEyzhqkn3qwOY7X0yGtbR3kh-Po1e_tDNUHT9Uxna8QrKIIv_2PEWYYE0CgasJ10ZlPPccIHI/?imgmax=800&quot; width=&quot;455&quot; height=&quot;410&quot; /&gt;&lt;/a&gt;&lt;/p&gt;          &lt;p&gt;&amp;#160;&lt;/p&gt;          &lt;p&gt;Click “OK” on the Job Properties pages. We now have a job with two steps to force all databases to fail over if one does, and to update the SQL Server Alias after that.&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;p&gt;Back on the Alert Property page, click “Ok” to finish creating the alert.&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;p&gt;We now have an Alert that will capture the event that a database has been manually failed over and take appropriate action. When the event occurs, the Alert is activated if the state value is 7. The Alert then executes the Job that was created, and the job executes the T-SQL code to fail over the remaining databases and then the batch file which executes the psexec utility to execute the batch file on the SharePoint server, which modifies the registry to change the server value for the SQL Server Alias.&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;p&gt;Of course you have to do the same for the other server in the mirroring set. The procedure is the same, just in reverse of what is shown here, as for which batch file to call when.&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;p&gt;That’s all for this post. Feel free to leave comments or ask questions. I’ll be happy to answer any. I’ve also included some useful links below.&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;h4&gt;Useful Links&lt;/h4&gt;          &lt;p&gt;&lt;a href=&quot;http://www.sqlservercentral.com/blogs/robert_davis/archive/2008/08/18/Automatically-respond-to-mirrored-database-failovers.aspx&quot; target=&quot;_blank&quot;&gt;SQL Server Central Blog&lt;/a&gt; &lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;p&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms188712.aspx&quot;&gt;http://msdn.microsoft.com/en-us/library/ms188712.aspx&lt;/a&gt;&lt;/p&gt;          &lt;p&gt;&lt;/p&gt;          &lt;p&gt;&lt;a href=&quot;http://www.mssqltips.com/tip.asp?tip=1564&quot;&gt;http://www.mssqltips.com/tip.asp?tip=1564&lt;/a&gt;&lt;/p&gt;          &lt;p&gt;           &lt;br /&gt;&lt;a href=&quot;http://blogs.technet.com/josebda/archive/2009/04/02/sql-server-2008-database-mirroring.aspx&quot; target=&quot;_blank&quot;&gt;Technet Blog On Mirroring&lt;/a&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt; Technorati Tags: &lt;a href=&quot;http://technorati.com/tags/SharePoint&quot; rel=&quot;tag&quot;&gt;SharePoint&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Server&quot; rel=&quot;tag&quot;&gt;Server&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Mirrors&quot; rel=&quot;tag&quot;&gt;Mirrors&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Database&quot; rel=&quot;tag&quot;&gt;Database&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Session&quot; rel=&quot;tag&quot;&gt;Session&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/installation&quot; rel=&quot;tag&quot;&gt;installation&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/cost&quot; rel=&quot;tag&quot;&gt;cost&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/client&quot; rel=&quot;tag&quot;&gt;client&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/method&quot; rel=&quot;tag&quot;&gt;method&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Some&quot; rel=&quot;tag&quot;&gt;Some&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Background&quot; rel=&quot;tag&quot;&gt;Background&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/product&quot; rel=&quot;tag&quot;&gt;product&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/FAILOVER&quot; rel=&quot;tag&quot;&gt;FAILOVER&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/PARTNER&quot; rel=&quot;tag&quot;&gt;PARTNER&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/connection&quot; rel=&quot;tag&quot;&gt;connection&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/options&quot; rel=&quot;tag&quot;&gt;options&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/settings&quot; rel=&quot;tag&quot;&gt;settings&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/configuration&quot; rel=&quot;tag&quot;&gt;configuration&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/danger&quot; rel=&quot;tag&quot;&gt;danger&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/addition&quot; rel=&quot;tag&quot;&gt;addition&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/databases&quot; rel=&quot;tag&quot;&gt;databases&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Microsoft&quot; rel=&quot;tag&quot;&gt;Microsoft&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/White&quot; rel=&quot;tag&quot;&gt;White&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Paper&quot; rel=&quot;tag&quot;&gt;Paper&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Office&quot; rel=&quot;tag&quot;&gt;Office&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Windows&quot; rel=&quot;tag&quot;&gt;Windows&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Services&quot; rel=&quot;tag&quot;&gt;Services&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Alias&quot; rel=&quot;tag&quot;&gt;Alias&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/data&quot; rel=&quot;tag&quot;&gt;data&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/servers&quot; rel=&quot;tag&quot;&gt;servers&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/documentation&quot; rel=&quot;tag&quot;&gt;documentation&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Front&quot; rel=&quot;tag&quot;&gt;Front&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Application&quot; rel=&quot;tag&quot;&gt;Application&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Registry&quot; rel=&quot;tag&quot;&gt;Registry&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/HKLM&quot; rel=&quot;tag&quot;&gt;HKLM&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/SOFTWARE&quot; rel=&quot;tag&quot;&gt;SOFTWARE&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/MSSQLServer&quot; rel=&quot;tag&quot;&gt;MSSQLServer&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/ConnectTo&quot; rel=&quot;tag&quot;&gt;ConnectTo&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Name&quot; rel=&quot;tag&quot;&gt;Name&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/REG_SZ&quot; rel=&quot;tag&quot;&gt;REG_SZ&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/port&quot; rel=&quot;tag&quot;&gt;port&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/batch&quot; rel=&quot;tag&quot;&gt;batch&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/development&quot; rel=&quot;tag&quot;&gt;development&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/folder&quot; rel=&quot;tag&quot;&gt;folder&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/SQLServerMirrorScripts&quot; rel=&quot;tag&quot;&gt;SQLServerMirrorScripts&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Note&quot; rel=&quot;tag&quot;&gt;Note&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/PowerShell&quot; rel=&quot;tag&quot;&gt;PowerShell&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/scripts&quot; rel=&quot;tag&quot;&gt;scripts&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/preference&quot; rel=&quot;tag&quot;&gt;preference&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/DBSERVERALIAS&quot; rel=&quot;tag&quot;&gt;DBSERVERALIAS&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/SQLAlias&quot; rel=&quot;tag&quot;&gt;SQLAlias&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/DBSERVER&quot; rel=&quot;tag&quot;&gt;DBSERVER&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/DBMSSOCN&quot; rel=&quot;tag&quot;&gt;DBMSSOCN&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/MOSS&quot; rel=&quot;tag&quot;&gt;MOSS&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/PSTools&quot; rel=&quot;tag&quot;&gt;PSTools&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Page&quot; rel=&quot;tag&quot;&gt;Page&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/user&quot; rel=&quot;tag&quot;&gt;user&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/context&quot; rel=&quot;tag&quot;&gt;context&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/argument&quot; rel=&quot;tag&quot;&gt;argument&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/execution&quot; rel=&quot;tag&quot;&gt;execution&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Again&quot; rel=&quot;tag&quot;&gt;Again&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/location&quot; rel=&quot;tag&quot;&gt;location&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/SharePointServer&quot; rel=&quot;tag&quot;&gt;SharePointServer&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/agreement&quot; rel=&quot;tag&quot;&gt;agreement&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/acceptance&quot; rel=&quot;tag&quot;&gt;acceptance&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Update&quot; rel=&quot;tag&quot;&gt;Update&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/response&quot; rel=&quot;tag&quot;&gt;response&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/automation&quot; rel=&quot;tag&quot;&gt;automation&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Service&quot; rel=&quot;tag&quot;&gt;Service&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Broker&quot; rel=&quot;tag&quot;&gt;Broker&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/mechanism&quot; rel=&quot;tag&quot;&gt;mechanism&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/event&quot; rel=&quot;tag&quot;&gt;event&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/notification&quot; rel=&quot;tag&quot;&gt;notification&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/SELECT&quot; rel=&quot;tag&quot;&gt;SELECT&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/FROM&quot; rel=&quot;tag&quot;&gt;FROM&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Management&quot; rel=&quot;tag&quot;&gt;Management&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Studio&quot; rel=&quot;tag&quot;&gt;Studio&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/ALTER&quot; rel=&quot;tag&quot;&gt;ALTER&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/ENABLE_BROKER&quot; rel=&quot;tag&quot;&gt;ENABLE_BROKER&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Agent&quot; rel=&quot;tag&quot;&gt;Agent&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/SQLSERVERAGENT&quot; rel=&quot;tag&quot;&gt;SQLSERVERAGENT&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/DATABASE_MIRRORING_STATE_CHANGE&quot; rel=&quot;tag&quot;&gt;DATABASE_MIRRORING_STATE_CHANGE&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/events&quot; rel=&quot;tag&quot;&gt;events&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/DBMirrorStateChange&quot; rel=&quot;tag&quot;&gt;DBMirrorStateChange&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Exists&quot; rel=&quot;tag&quot;&gt;Exists&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Where&quot; rel=&quot;tag&quot;&gt;Where&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Begin&quot; rel=&quot;tag&quot;&gt;Begin&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Create&quot; rel=&quot;tag&quot;&gt;Create&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/DBMirrorService&quot; rel=&quot;tag&quot;&gt;DBMirrorService&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/DROP&quot; rel=&quot;tag&quot;&gt;DROP&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/QUEUE&quot; rel=&quot;tag&quot;&gt;QUEUE&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/State&quot; rel=&quot;tag&quot;&gt;State&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Description&quot; rel=&quot;tag&quot;&gt;Description&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Null&quot; rel=&quot;tag&quot;&gt;Null&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Principal&quot; rel=&quot;tag&quot;&gt;Principal&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Mirror&quot; rel=&quot;tag&quot;&gt;Mirror&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Lost&quot; rel=&quot;tag&quot;&gt;Lost&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/instance&quot; rel=&quot;tag&quot;&gt;instance&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Manual&quot; rel=&quot;tag&quot;&gt;Manual&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Automatic&quot; rel=&quot;tag&quot;&gt;Automatic&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/mode&quot; rel=&quot;tag&quot;&gt;mode&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/instances&quot; rel=&quot;tag&quot;&gt;instances&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/error&quot; rel=&quot;tag&quot;&gt;error&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Quorum&quot; rel=&quot;tag&quot;&gt;Quorum&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/backlog&quot; rel=&quot;tag&quot;&gt;backlog&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/status&quot; rel=&quot;tag&quot;&gt;status&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/protection&quot; rel=&quot;tag&quot;&gt;protection&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Alert&quot; rel=&quot;tag&quot;&gt;Alert&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/SSMS&quot; rel=&quot;tag&quot;&gt;SSMS&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/script&quot; rel=&quot;tag&quot;&gt;script&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Locate&quot; rel=&quot;tag&quot;&gt;Locate&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/node&quot; rel=&quot;tag&quot;&gt;node&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/tree&quot; rel=&quot;tag&quot;&gt;tree&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Alerts&quot; rel=&quot;tag&quot;&gt;Alerts&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Enter&quot; rel=&quot;tag&quot;&gt;Enter&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Type&quot; rel=&quot;tag&quot;&gt;Type&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Namespace&quot; rel=&quot;tag&quot;&gt;Namespace&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/jobs&quot; rel=&quot;tag&quot;&gt;jobs&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Query&quot; rel=&quot;tag&quot;&gt;Query&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Execute&quot; rel=&quot;tag&quot;&gt;Execute&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/properties&quot; rel=&quot;tag&quot;&gt;properties&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/dialog&quot; rel=&quot;tag&quot;&gt;dialog&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/owner&quot; rel=&quot;tag&quot;&gt;owner&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/category&quot; rel=&quot;tag&quot;&gt;category&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Local&quot; rel=&quot;tag&quot;&gt;Local&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/purpose&quot; rel=&quot;tag&quot;&gt;purpose&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Steps&quot; rel=&quot;tag&quot;&gt;Steps&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Button&quot; rel=&quot;tag&quot;&gt;Button&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Step&quot; rel=&quot;tag&quot;&gt;Step&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/System&quot; rel=&quot;tag&quot;&gt;System&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/CmdExec&quot; rel=&quot;tag&quot;&gt;CmdExec&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/account&quot; rel=&quot;tag&quot;&gt;account&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Command&quot; rel=&quot;tag&quot;&gt;Command&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Back&quot; rel=&quot;tag&quot;&gt;Back&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/action&quot; rel=&quot;tag&quot;&gt;action&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/card&quot; rel=&quot;tag&quot;&gt;card&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/disks&quot; rel=&quot;tag&quot;&gt;disks&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Fail&quot; rel=&quot;tag&quot;&gt;Fail&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Over&quot; rel=&quot;tag&quot;&gt;Over&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Transact&quot; rel=&quot;tag&quot;&gt;Transact&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Leave&quot; rel=&quot;tag&quot;&gt;Leave&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Code&quot; rel=&quot;tag&quot;&gt;Code&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/NOCOUNT&quot; rel=&quot;tag&quot;&gt;NOCOUNT&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/DECLARE&quot; rel=&quot;tag&quot;&gt;DECLARE&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/NVARCHAR&quot; rel=&quot;tag&quot;&gt;NVARCHAR&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/MyCursor&quot; rel=&quot;tag&quot;&gt;MyCursor&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/CURSOR&quot; rel=&quot;tag&quot;&gt;CURSOR&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/INNER&quot; rel=&quot;tag&quot;&gt;INNER&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/JOIN&quot; rel=&quot;tag&quot;&gt;JOIN&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/OPEN&quot; rel=&quot;tag&quot;&gt;OPEN&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/FETCH&quot; rel=&quot;tag&quot;&gt;FETCH&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/INTO&quot; rel=&quot;tag&quot;&gt;INTO&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Fetch_Status&quot; rel=&quot;tag&quot;&gt;Fetch_Status&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/EXEC&quot; rel=&quot;tag&quot;&gt;EXEC&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/CLOSE&quot; rel=&quot;tag&quot;&gt;CLOSE&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/DEALLOCATE&quot; rel=&quot;tag&quot;&gt;DEALLOCATE&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/exception&quot; rel=&quot;tag&quot;&gt;exception&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Click&quot; rel=&quot;tag&quot;&gt;Click&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/procedure&quot; rel=&quot;tag&quot;&gt;procedure&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Feel&quot; rel=&quot;tag&quot;&gt;Feel&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Useful&quot; rel=&quot;tag&quot;&gt;Useful&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Links&quot; rel=&quot;tag&quot;&gt;Links&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Central&quot; rel=&quot;tag&quot;&gt;Central&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Blog&quot; rel=&quot;tag&quot;&gt;Blog&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/library&quot; rel=&quot;tag&quot;&gt;library&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Technet&quot; rel=&quot;tag&quot;&gt;Technet&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/psexec&quot; rel=&quot;tag&quot;&gt;psexec&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/synchronous&quot; rel=&quot;tag&quot;&gt;synchronous&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/strSQL&quot; rel=&quot;tag&quot;&gt;strSQL&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/strDatabasename&quot; rel=&quot;tag&quot;&gt;strDatabasename&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/database_id&quot; rel=&quot;tag&quot;&gt;database_id&lt;/a&gt;  &lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script expr:src=&#39;&quot;http://feeds.feedburner.com/~s/SlingingSql?i=&quot; + data:post.url&#39; type=&quot;text/javascript&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;&lt;/div&gt;</description><link>http://sqlslinger.blogspot.com/2010/04/sharepoint-on-sql-server-mirrors.html</link><author>noreply@blogger.com (Dan Ward)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqa08e4tc7xaDU0p1-TTzH11Pe4GnX8cXKmdq9qdgebdLkGhheZQFl7pkQrQ-4iBJkMixO2sa0LvqFGjUuhUVxtJJQ1zbsgiEhdt2sXbuZ7XeDWvaP8sCmpD8e0aThfrMqR7ePdnz9I5M/s72-c?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6367058912647240061.post-2396946632727638374</guid><pubDate>Fri, 26 Feb 2010 04:28:00 +0000</pubDate><atom:updated>2010-02-25T23:30:20.085-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Automatic Failover</category><category domain="http://www.blogger.com/atom/ns#">Disaster Recovery</category><category domain="http://www.blogger.com/atom/ns#">High Availability</category><category domain="http://www.blogger.com/atom/ns#">Mirror</category><category domain="http://www.blogger.com/atom/ns#">Mirroring</category><category domain="http://www.blogger.com/atom/ns#">Principal</category><category domain="http://www.blogger.com/atom/ns#">SQL Server 2008</category><category domain="http://www.blogger.com/atom/ns#">SSMS</category><category domain="http://www.blogger.com/atom/ns#">Tools</category><category domain="http://www.blogger.com/atom/ns#">Witness</category><title>Database Mirroring on SQL Server 2008</title><description>&lt;p&gt;I know it has been a very long time since I posted, and for that I am sorry. Sometimes work and personal life conspire to evaporate any free time you might have. But here I am with a new and hopefully useful bit of hard won experience to share with you.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;I was recently engaged at a client to assist them with implementing database mirroring on SQL Server 2008. Everything seemed straight forward enough, they were conducting a proof of concept (POC) around using SQL Server to host their new ERP system and needed to prove the high availability features of automatic failover. No problem so far. They had a primary and secondary server and a virtual server to act as the witness already in place.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;The wrench got thrown in at our kick-off meeting when the client informed me that since they are already implementing SharePoint 2007, they want the POC to use SharePoint as the application that will utilize the mirrored database set up. I’m not sure how many of you know this, but in order for an application to be natively ready to utilize a SQL Server mirrored environment and facilitate automatic fail-over, it must be capable of implementing the FAILOVER PARTNER attribute of a mirroring aware data source. SharePoint does not. There are many posts around the net on DB Mirroring, and SharePoint on mirrors, but I failed to find a comprehensive source that provided all the information I needed. Hence, my contribution to the community via this post. Actually this and the next post. I plan to break it up into a pair of posts, one that deals with the setting up of the mirroring, and one that deals specifically with the steps necessary to implement SharePoint on the mirroring session and provide automatic fail-over.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;So in this post we will go through the process of creating a mirroring session and implementing mirroring for a database. We’ll use the AdventureWorks2008 sample database that Microsoft was so kind to create for us.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Any time you embark on configuring something in SQL Server, it is a good idea to be sure all the prerequisites are met ahead of time. There is a good source for prerequisites on SQL Server database mirroring at Microsoft TechNet. Here is the link &lt;a title=&quot;Prerequisites, Restrictions, and Recommendations for Database Mirroring&quot; href=&quot;http://technet.microsoft.com/en-us/library/ms366349.aspx&quot;&gt;Prerequisites, Restrictions, and Recommendations for Database Mirroring&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Some things to note: Make sure both partners are using the same version and EDITION of SQL Server 2008. If you are running Enterprise on the primary, you should run Enterprise on the secondary. Both servers should also utilize the same default collation. You can not implement mirroring on database servers that have implemented the FILESTREAM option. Use of a third server, which can be a different Edition of SQL Server 2008, even EXPRESS, is required to fill the role of witness if you are implementing high availability mode (high safety with automatic fail-over).&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;So let’s begin. The first step is to ensure we have 3 server instances available to us. In a production application, these will be 3 separate servers, even if any or all are virtual. If you are doing this on your own, you can install a named instance of SQL Server along with your default instance and install SQL Server Express to act as the witness.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Once you have established your servers, you will need to ensure you have met all the requirements and pre-requirements as laid out in the above link. When you are ready to begin, follow the steps below.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Step 1:    &lt;br /&gt;Set Recovery Model to FULL.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGhEikYcUt9vyJbBPz5UHhvVrlvooj6OvLMYpzOwI9a3wbfjRahmCnItlLa0MobWawqR7SqsjVfEJHOMo-fRcQzE0LqE0B4S1SsCHS4u1NpaPFD5Nf83qArDttCmLuff6jQglXbjcqUgs/s1600-h/Mirroring_AdvWrks14.png&quot;&gt;&lt;img style=&quot;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&quot; title=&quot;Mirroring_AdvWrks1&quot; border=&quot;0&quot; alt=&quot;Mirroring_AdvWrks1&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrsRL3qa76pUAyd2NP9W2mvFY1YAtfGkxaHP_fbJwHIPLcVnOz82EAq3cRp0fsWWqAckE0THuDRgYJYb_wzAvNZ5IU2MBUX_TbPw_PHNMRMN3CkT6a6O3WskimZixrKESIwqxGtQ57GIM/?imgmax=800&quot; width=&quot;448&quot; height=&quot;402&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiN8aRs5kLU8q1n1bhXP6wyavf94xuHG_gv4wwwNn0lRZSckP3nychXNf46lyAnthBN8dYGcibctqTqBNpUKuXDg4SGd2cmfOJLMvMGpJAT3RB8FuNcOGIRs6zTDzuvZ_Ayk1u8eR6JHFI/s1600-h/Mirroring_AdvWrksRecoveryFull3.png&quot;&gt;&lt;img style=&quot;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&quot; title=&quot;Mirroring_AdvWrksRecoveryFull&quot; border=&quot;0&quot; alt=&quot;Mirroring_AdvWrksRecoveryFull&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwY7ortwzqCR2s-vY_H14ez-ogKVvS1M4ODcwkfTsQFLD-_0G7H982Gr-SnwNsoCtXJpqJ9My5f6V7qompux7iRaGOSONrA0NqmCbinQgpMEOMzPn9UKBNiL1EreVbkjj_QzqZfN1Uvwo/?imgmax=800&quot; width=&quot;338&quot; height=&quot;62&quot; /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Step 2:    &lt;br /&gt;Backup the database.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt; &lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjZdecWcicV_RiXk61LK2Hb6mC9JXtkt-m_DVDSKMGWrOEjygQkANCn-n6PP2JwtX94TyId8NoRVT0A-G8IeaPdCsVQd6-yO0MIwgXkzBcoPxwIwqOhkTDSpDeGsBe0qV8n2TMHtGoOFw/s1600-h/Mirroring_AdvWrksBackup4.png&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; title=&quot;Mirroring_AdvWrksBackup&quot; border=&quot;0&quot; alt=&quot;Mirroring_AdvWrksBackup&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4E_fDuWA1c6HsPVOZhdjYLpEFIt29ZI_abhaD6VY-TFh9h_leW5geg6kZYA5ZWZz00-x2ncLjD1xe4ef-XNIXsqqcl1FhhmUpLPFYGKKTM0-sdV2GLEkb-lbP16mbVNKpaIy7LLSXTnM/?imgmax=800&quot; width=&quot;450&quot; height=&quot;404&quot; /&gt;&lt;/a&gt;   &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p style=&quot;width: 437px; height: 0.84%&quot;&gt;&lt;/p&gt;  &lt;p&gt;Step 3:    &lt;br /&gt;Copy the backup to the designated mirror instance.     &lt;br /&gt;Step 4:     &lt;br /&gt;Restore the backup on the designated mirror instance with the options selected as below.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiefIYM4N2lbYc3W2fBmzCRDthdL3WRPyZJmMQHpAaeLOiCLv73eeJum6mn_1L8yvh5Ng77jhCKfRwcCIVCmrbyjrwkFdROW4EbAbzi8EQusSbAQonalE1FJKgZ7d7PvqTuSQh84-K3di8/s1600-h/Mirroring_AdvWrksRestore1%5B4%5D.png&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; title=&quot;Mirroring_AdvWrksRestore1&quot; border=&quot;0&quot; alt=&quot;Mirroring_AdvWrksRestore1&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3xEjf3R3kjiXTzKdgVs67m-uOg7WJVvvwr4e2VXqnosPjOVQ-WdFebucHA_iFwKE7wwSM9UvQQvoJXwoGvzOgW_NOMndjvvCV33eSrdfff0I-_10CZXqkTnl48NdmbrluXeqYJ0njg50/?imgmax=800&quot; width=&quot;453&quot; height=&quot;350&quot; /&gt;&lt;/a&gt;&lt;/p&gt; &lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2iVUkHK3ZsmX1WLHNNZvDmImoRwrrALHMnnGiwpugh8v6R5Bf8YR-ECFZg4m_obGij7U6SfkUH71B-T1qEJCmPSdoSbLQsgzfq4PJHt1toMMrOZ_-Pj1miDo8YAE1Mu9VR2bAvDaLhJM/s1600-h/Mirroring_AdvWrksRestore2%5B3%5D.png&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; title=&quot;Mirroring_AdvWrksRestore2&quot; border=&quot;0&quot; alt=&quot;Mirroring_AdvWrksRestore2&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSjwUaeh1Rc141D6-gRZaYJ9oENp_5nMaxR8gBjX6CDf5fLVW2d5TRXUJM62wUJOHhWJIpgqQH-9335O5JHQ3AKJHOPXfuzgf0ezfKdKaHIJgS7jwC7YZPfvxh1d1NZrgB1FAE0CKRM60/?imgmax=800&quot; width=&quot;456&quot; height=&quot;352&quot; /&gt;&lt;/a&gt;   &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;You must choose the “Leave the database non-operational, and do not roll back uncommitted transactions. Additional transaction logs can be restored (RESTORE WITH NORECOVERY)” option for database mirroring.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Step 5:    &lt;br /&gt;On the designated principal instance, right click the database and select “Tasks” and then “Mirror”. This will launch the Database Mirroring Wizard.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg42XS5GMlngSBlwA-KMhLslo7XwGU9f0X6liLYvr_X_hZnquwv80SG-rGBMg1bsQz2r1U0E2CdfRYsgltUC-3RwvVbKlX-Rm9MOVq9MsNJqRuQPVM5OdmlSbIhd-zUCs5vuDXEqucaNkU/s1600-h/Mirroring_AdvWrksMirrorWiz2%5B3%5D.png&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; title=&quot;Mirroring_AdvWrksMirrorWiz2&quot; border=&quot;0&quot; alt=&quot;Mirroring_AdvWrksMirrorWiz2&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZF5GGMMPMXLSchzlBFELDbgHul54vhP8-GkShdXSTSoLmqhFqFLW2lxbYR_cmE0qYWPs791prSWLcZuwQnjPACBHKHAJqz8Tr_0HJlbtej5MdE5Xe7A-lCy3bqffW6jYiu4YEQdfoBfA/?imgmax=800&quot; width=&quot;454&quot; height=&quot;411&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Click “Next” and move through the wizard, selecting the Principal or primary server, the secondary or Mirror server, and the Witness server. In order to achieve automatic fail over a witness server is required.&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBbqfM8zPK-BZKKWJxzJBmU6LhpbtxRy6bxw5wdnUiyaZri8KwMETsRxYERoiyGYzzXmaCHL8g8640-o1ut_xq4ZN2cvZ0B8nXLA40CLiu_CODBs06o8LaGey7tovm3OGb4mAC6TX2RAg/s1600-h/Mirroring_AdvWrksMirrorWiz3%5B3%5D.png&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; title=&quot;Mirroring_AdvWrksMirrorWiz3&quot; border=&quot;0&quot; alt=&quot;Mirroring_AdvWrksMirrorWiz3&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWgZBDRuAf-5nOrC19CEHRizM7mMixzAqPEb7thNr1ir8Gg-vKZd9c5BGctgQZTLnXhs_QD1a-t9FzvUzNBtD7cTwhVqztm7qxOf7SUSGdCiQLsDuUq53mjri4_DaQbOdIFa4k3igjCGA/?imgmax=800&quot; width=&quot;455&quot; height=&quot;412&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGK2S0bBo_Z0y7DyIMo5zNswKrxgBP74Sy48OSTW4UUxeCKhvSOgpwQUSQcDkF2ioBIi0Ua5JQ8466PDQHG-ORvmroqiyyHEaZKoYHjWdwTrTGPfnMyXxvGOkHduRiQ3FPqWoFaTyLB4g/s1600-h/Mirroring_AdvWrks4%5B3%5D.png&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; title=&quot;Mirroring_AdvWrks4&quot; border=&quot;0&quot; alt=&quot;Mirroring_AdvWrks4&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRT6iFCdryQ0LvOx-5FgG2qpP4ZU0wIJ6qS3UjIlW5ajmGAbjvfKcM8g0Tm66fXGu2M_kz5P9Cwy9W2x26a0crcqRS-Wtr1LUvrLd6Bz2N7DCm6r4BbKG56xTpZDP2hJZz1ZEouPfKnI4/?imgmax=800&quot; width=&quot;456&quot; height=&quot;413&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;There will be an identical screen on which to select the Witness server. The wizard creates and configures the endpoints for you.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvICKRkm9Zd2Ma7Y8mxsWxJho11El7ONphEpjJkAIAzLx3INhaWpTwHxrY1ftt1tn8qU31EP5tGH1YisOcnJRsa6S_ywe4kdbTYOCzlI_ZAWElJ7MUqyJbUFT7fOday_ThXhVjUyNTmzc/s1600-h/Mirroring_AdvWrksMirrorWiz5%5B3%5D.png&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; title=&quot;Mirroring_AdvWrksMirrorWiz5&quot; border=&quot;0&quot; alt=&quot;Mirroring_AdvWrksMirrorWiz5&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYa9xbwd-RgXoq86P__uESeNxORDcGXrxku-kiIMTnJqluAFECaYxz_1bl01HPGJiLOwaD0tpPiHFbpmXHk-z2-YflXP61o_KPLGSRv1trwj79NfgWHmbrvOif-9u-lxmywEqvIHQvDNA/?imgmax=800&quot; width=&quot;458&quot; height=&quot;414&quot; /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;These accounts are used for communication between the three servers.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJP3-SaPjo5liRZxhKz3S7OgKYo3NqI3S79kzA56vd0p59FpfdvOz5Yz18p42lpnuQzckKixHNABLkLKxqzDM5xR6lRLNT2R7-HTsXAe-HaaUlTATV9BnSB2IFF4uDHfGRE6z8Yd_WZNs/s1600-h/Mirroring_AdvWrksMirrorWiz6%5B3%5D.png&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; title=&quot;Mirroring_AdvWrksMirrorWiz6&quot; border=&quot;0&quot; alt=&quot;Mirroring_AdvWrksMirrorWiz6&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhm-RJ3MHVTzxx3GXIrB2qfFcw4ezf8Iw2RwQqPIG55bADeXjwIyJvN9IbtA3OtGRXcJK8w2Y8gZl6UuFfSpUHadnoPkHB0TznIylFnK2c1B-FfTjaqnMV451oTmMfqc7xyR7aiBie0zYo/?imgmax=800&quot; width=&quot;459&quot; height=&quot;415&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Final check before finishing.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuzSSMZ0sKRixK5HcPNnuca4jjPaL75jDtEEtTfx7ttqnEvuwQ8tl_N2d5nCBsFDtzmEuZRBmHDPZpLcBEhTYE1K3bDH8ixP9Wogi1uxapNqsk4vy6y5Ws51h9zS0BZWw244v9kZgzRbA/s1600-h/Mirroring_AdvWrksMirrorWiz7%5B4%5D.png&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; title=&quot;Mirroring_AdvWrksMirrorWiz7&quot; border=&quot;0&quot; alt=&quot;Mirroring_AdvWrksMirrorWiz7&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0MBcpuRNaVbZTNPpjw6HL6nk3avt1YsYjOf8QzWHbeLIfT8q8Uvx2h845aPEWLCg0rNpygGH1L9SjQo5UQaWm24AAHYmU47GsZVUr_cRXwxDZ0dS6x9knEWY6saVP1FEiUbFPVaBqpUY/?imgmax=800&quot; width=&quot;452&quot; height=&quot;409&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;This screen shows the configuration progress for each server. Any warnings or errors will be caught and displayed here. When this screen finishes, you will be prompted to start mirroring.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0f_bxZYSc6ASjORXUKEgfGKljt6DTZokmVP_HPDh0OkY6rCJToWkwfZy7pvvq_I6D_t_eoncGdMeuBk634Aevqhjk2YqbxHKonZlTe4JST_RY4_Pc3_xcVX0Doeo0qTXNPc4SBBLcxjA/s1600-h/Mirroring_AdvWrksStartMirror1%5B3%5D.png&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; title=&quot;Mirroring_AdvWrksStartMirror1&quot; border=&quot;0&quot; alt=&quot;Mirroring_AdvWrksStartMirror1&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbD-5FtL2BeAJG6opgLPY69EPcJc0bIM8ttY2JThBWPzhX5DkmhBzJQRbjJcgH558KCjKA7z3y5pcOpDFU8-CNjBhCRbf1D0-7tcGTKeFk-ufVMAt2uA8Xt5efCH1Q42Qa7cWcop_bzzU/?imgmax=800&quot; width=&quot;451&quot; height=&quot;192&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Once the process concludes and the databases have synchronized, the mirroring session is started and all transactions made at the principal will be duplicated on the mirror. In the event of a failure of the primary/principal the Witness and the Mirror form a quorum and determine to switch control to the mirror, which exits the restoring state and becomes a disconnected principal. When the mirroring session is started the Mirror page of the database properties is as shown below.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOsJnOo8x5vQJcA80fPG4Q-lOm5AfqJFmrW5yu26X42fxFaA5hI0RhYuyl8mZ8gqaWLubaKBFpqvHV0xXlVDtj4_0IuQR8e6cRzZcbmwyQ0QjddA5TzcM5eAs2xnqx5ioY3pNq7XmZAuo/s1600-h/Mirroring_AdvWrksMirroringComplete%5B3%5D.png&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; title=&quot;Mirroring_AdvWrksMirroringComplete&quot; border=&quot;0&quot; alt=&quot;Mirroring_AdvWrksMirroringComplete&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgS-wGWwRlztZEJD7qjB5feoY-4CtDN5hsG2bjmnnL5cge2CWvOtC_NkFpQTxW6dt9EEYDLcc40O1yu2018WK6zCz22yKwmraAq6dHhQxB9xIEbz6vrcFUdEGtXdFHVvWEx6liS2afdZQ8/?imgmax=800&quot; width=&quot;453&quot; height=&quot;406&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;You will see in the database object tree view in SQL Server Management Studio, that one database shows Principal, synchronized, and one shows Mirror, synchronized.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjo0sBDtJX6gMCiKy1b5_vxErpPfLhPH6ygkhBcsCEAQi-YDaRdA3zdU8MjQ3At3CqWLL56bS19HyEh0Z6EoCkDpzH7-bgAooqVH0kAYu0g8rtiilvdavBGX10RdYnqFS-WI-j1Mk2GRu4/s1600-h/Mirroring_DB_View%5B7%5D.png&quot;&gt;&lt;img style=&quot;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&quot; title=&quot;Mirroring_DB_View&quot; border=&quot;0&quot; alt=&quot;Mirroring_DB_View&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifQ5HWbCEmNOIcNzl4w91pZWAPLWRWN-Th-voG2f_MdKxDyeXD0zT178ydN6m5qU_GnYwfZa_OKiP73JWc3ac45TWRpyn28LHaUqMtRRPs-OSeYC_zue3PFE2Z6rtbEht5lr9O4Cp-iC8/?imgmax=800&quot; width=&quot;355&quot; height=&quot;483&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;That’s it. You have set up mirroring on your database. Now when a problem occurs with the principal, the mirror will take over operation as the principal database. Any mirroring aware applications can implement the FAILOVER PARTNER attribute of the connection string to ensure continuous operation through a failed database server.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;You can manual fail over the database from primary server to the secondary server in two ways. &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;One: Open the properties for the database and select the Mirror page. There is a button “Failover” that if you press, will manually fail over the database from the primary to the secondary.    &lt;br /&gt;Two: You can issue a T-SQL Query to fail over the database. On the primary server with the principal database execute the following code;     &lt;br /&gt;&lt;font color=&quot;#0000ff&quot;&gt;ALTER DATABASE&lt;/font&gt; AdventureWorksDW &lt;font color=&quot;#0000ff&quot;&gt;SET PARTNER FAILOVER&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;That’s all there is too setting it up. Of course there is a ton more information on Microsoft MSDN and TechNet as well as in BOL. Look it up, there’s much, much more to learn about database mirroring.&lt;/p&gt; In my next post we will continue from here and implement automatic failover for a SharePoint installation. Until thin, keep slinging the SQL.    &lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script expr:src=&#39;&quot;http://feeds.feedburner.com/~s/SlingingSql?i=&quot; + data:post.url&#39; type=&quot;text/javascript&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;&lt;/div&gt;</description><link>http://sqlslinger.blogspot.com/2010/02/database-mirroring-on-sql-server-2008.html</link><author>noreply@blogger.com (Dan Ward)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrsRL3qa76pUAyd2NP9W2mvFY1YAtfGkxaHP_fbJwHIPLcVnOz82EAq3cRp0fsWWqAckE0THuDRgYJYb_wzAvNZ5IU2MBUX_TbPw_PHNMRMN3CkT6a6O3WskimZixrKESIwqxGtQ57GIM/s72-c?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6367058912647240061.post-1468824031289232247</guid><pubDate>Tue, 18 Nov 2008 14:21:00 +0000</pubDate><atom:updated>2008-11-18T11:00:59.028-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Audit</category><category domain="http://www.blogger.com/atom/ns#">Auditing</category><category domain="http://www.blogger.com/atom/ns#">Change Data</category><category domain="http://www.blogger.com/atom/ns#">Change Tracking</category><category domain="http://www.blogger.com/atom/ns#">History</category><category domain="http://www.blogger.com/atom/ns#">Row Versioning</category><category domain="http://www.blogger.com/atom/ns#">SQL Server 2008</category><category domain="http://www.blogger.com/atom/ns#">T-SQL</category><category domain="http://www.blogger.com/atom/ns#">Tracking</category><category domain="http://www.blogger.com/atom/ns#">Version</category><title>Change Tracking (Not CDC)</title><description>&lt;p&gt;Change Tracking has a similar name to Change Data Capture and has caused some minor confusion. Change Tracking, however, is entirely different and serves a separate purpose.&lt;/p&gt;  &lt;p&gt;CDC is an asynchronous process that captures row level changes and stores them in special change tables. This information is available as relational data and can be queried by client applications.&lt;/p&gt;  &lt;p&gt;Change Tracking is synchronous and tracks data changes but stores only the fact that they were changed and the last value for the row. Both one-way and two-way synchronization is supported, but remember that with two-way conflict detection is supported but the client&amp;#160; is responsible for handling it.&lt;/p&gt;  &lt;p&gt;Change Tracking uses tracking tables to store the primary key of the modified rows along with version numbers. It is easy to detect version conflicts. &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;An application requests the version number for a row it intends to modify. &lt;/li&gt;    &lt;li&gt;If the version has changed since the last request, there is a conflict.&lt;/li&gt;    &lt;li&gt;Solving the conflict is up to the requesting application.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;In order to work with Change Tracking there are a few steps to do. &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Enable Change Tracking at the database level.&lt;/li&gt;    &lt;li&gt;Enable Change Tracking at the table level.&lt;/li&gt;    &lt;li&gt;Use CHANGE_TRACKING_MIN_VALID_VERSION function to get the minimum version, which is an integer. This value can be used to get the changes for a specific table.&lt;/li&gt;    &lt;li&gt;Use CHANGETABLE function to get information , such as changes, types of changes, columns that changed, etc.&lt;/li&gt;    &lt;li&gt;Use CHANGE_TRACKING_CURRENT_VERSION function to get the current version. This is set by the last transaction committed in the database.&lt;/li&gt;    &lt;li&gt;Use the WITH CHANGE_TRACKING_CONTEXT() hint to specify a context for data modifications. This allows data modifications to be grouped according to client or application.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Let&#39;s look at some code that will show some of the basics.&lt;/p&gt;  &lt;div&gt;   &lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;USE master;
GO
--Create a test database if necessary
IF NOT EXISTS(SELECT * FROM sys.databases WHERE [name]=N&#39;MyDB&#39;)
    CREATE DATABASE MyDB;
GO
--Configure the database to allow change tracking
IF NOT EXISTS(SELECT * FROM sys.change_tracking_databases 
WHERE database_id = (SELECT database_id FROM sys.databases WHERE [name]=N&#39;MyDB&#39;))
    ALTER DATABASE MyDB SET CHANGE_TRACKING = ON 
    (CHANGE_RETENTION = 2 DAYS, AUTO_CLEANUP = ON);
GO
--Configure the database to use snapshot isolation
ALTER DATABASE MyDB SET ALLOW_SNAPSHOT_ISOLATION ON;
GO
USE MyDB;
GO
--Create a test table
IF NOT EXISTS(SELECT * FROM sys.tables WHERE [name]=N&#39;testTbl&#39;)
    CREATE TABLE testTbl(testID INT IDENTITY(1,1) PRIMARY KEY 
    NOT NULL, VAL VARCHAR(64));
GO
--Enable change tracking on the table
IF NOT EXISTS(SELECT * FROM sys.change_tracking_tables WHERE [object_id] = OBJECT_ID(N&#39;testTbl&#39;))
    ALTER TABLE testTbl ENABLE CHANGE_TRACKING;
GO
--Examples of using the Change Tracking functions.
SELECT CHANGE_TRACKING_CURRENT_VERSION();
SELECT CHANGE_TRACKING_MIN_VALID_VERSION(OBJECT_ID(N&#39;testTbl&#39;));INSERT INTO testTbl(VAL) VALUES(&#39;V01&#39;);
SELECT CHANGE_TRACKING_CURRENT_VERSION();
SELECT CHANGE_TRACKING_MIN_VALID_VERSION(OBJECT_ID(N&#39;testTbl&#39;));
INSERT INTO testTbl(VAL) VALUES(&#39;V02&#39;),(&#39;V03&#39;),(&#39;V04&#39;);
SELECT CHANGE_TRACKING_CURRENT_VERSION();
SELECT CHANGE_TRACKING_MIN_VALID_VERSION(OBJECT_ID(N&#39;testTbl&#39;));&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
  &lt;br /&gt;The example code above shows the initial values for Change Tracking as well as the changes when you update a row&#39;s data. To use Change Tracking you need to reconnect to check that you have a valid version of the data before you process it. Below shows the one-way synchronization scenario.&lt;/p&gt;

&lt;div&gt;
  &lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;--This shows the one way sync scenario
SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
DECLARE @Last_sync_version INT = 0;
DECLARE @sync_version INT;
--Use transaction for consistency
BEGIN TRANSACTION
--Make sure the last_sync_version is valid
IF (@Last_sync_version &lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt; CHANGE_TRACKING_MIN_VALID_VERSION(OBJECT_ID(N&#39;testTbl&#39;)))
    RAISERROR(N&#39;Invalid value&#39;, 10, 1);
ELSE
BEGIN
    --Get the current for the next sync
    SET @sync_version = CHANGE_TRACKING_CURRENT_VERSION();
    --Show the current tracking version and change version
    --for each row.
    SELECT testTbl.testID, testTbl.VAL, CT.SYS_CHANGE_VERSION CV,
        CT.SYS_CHANGE_CREATION_VERSION CCV, CT.SYS_CHANGE_OPERATION CO,
        CT.SYS_CHANGE_COLUMNS CC, CT.SYS_CHANGE_CONTEXT CContext
    FROM CHANGETABLE(CHANGES testTbl, @Last_sync_version) AS CT
    LEFT JOIN testTbl ON testTbl.testID = CT.testID;
    SELECT @sync_version;
END
COMMIT TRANSACTION
GO

--Show another session updating the data
UPDATE testTbl SET VAL=&#39;New V01&#39; WHERE testID = 1;
INSERT INTO testTbl(VAL) VALUES(&#39;V05&#39;);
DELETE FROM testTbl WHERE testID = 3;

--The initial session reconnects to get
--changes
SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
DECLARE @Last_sync_version INT = 2;
DECLARE @sync_version INT;
BEGIN TRANSACTION
--Check that you have a valid version
IF(@Last_sync_version &lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt; CHANGE_TRACKING_MIN_VALID_VERSION(OBJECT_ID(N&#39;testTbl&#39;)))
    RAISERROR(N&#39;Invalid value&#39;, 10, 1);
ELSE
BEGIN
    SET @sync_version = CHANGE_TRACKING_CURRENT_VERSION();
    SELECT testTbl.testID, testTbl.VAL, CT.SYS_CHANGE_VERSION CV,
        CT.SYS_CHANGE_CREATION_VERSION CCV, CT.SYS_CHANGE_OPERATION CO,
        CT.SYS_CHANGE_COLUMNS CC, CT.SYS_CHANGE_CONTEXT CContext
    FROM CHANGETABLE(CHANGES testTbl, @Last_sync_version) AS CT
    LEFT JOIN testTbl ON testID.Tbl.MyID = CT.MyID;
    SELECT @sync_version;
END
COMMIT TRANSACTION
GO&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
  &lt;br /&gt;There is also two-way synchronization, which is shown below. In the scenario shown, an attempt is made to update the first row. If it can&#39;t update the row, the execution path follows the conflict resolution code. This example only uses a table with 2 columns, but in real-world scenarios a table will have far more columns, some of which may have been updated. In this situation, if you are updating columns in a table that haven&#39;t been updated, you may choose to proceed.&lt;/p&gt;

&lt;div&gt;
  &lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;--Two-way synchronization scenario.
--Assumes the last sync occurred when the sync value was 2
SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
DECLARE @Last_sync_version INT = 2;
DECLARE @sync_version INT;
DECLARE @current_row_version INT;
--Find the current row version for testID=1
SELECT @current_row_version = ISNULL((SELECT CT.SYS_CHANGE_VERSION 
FROM CHANGETABLE(VERSION testTbl, (testID), (1)) CT),0)
SELECT @current_row_version;
BEGIN TRANSACTION
IF (@Last_sync_version &lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt; CHANGE_TRACKING_MIN_VALID_VERSION(OBJECT_ID(N&#39;testTbl&#39;)))
    RAISERROR(N&#39;Invalid value&#39;,10,1);
ELSE
BEGIN
    --Attempt to update the 1st row
    UPDATE testTbl SET VAL = &#39;NewAppValue&#39;
    FROM testTbl WHERE testID = 1 AND @Last_sync_version &lt;span style=&quot;color: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;= @current_row_version;
END
IF (@@ROWCOUNT = 0)
BEGIN
    --A conflict is indicated by the execution path (@@ROWCOUNT = 0)
    --Gather more information to see if the VAL column has been updated.
    IF EXISTS(SELECT CHANGE_TRACKING_IS_COLUMN_IN_MASK(2, CT.SYS_CHANGE_COLUMNS) CC
    FROM CHANGETABLE(CHANGES testTbl,@Last_sync_version) CT
    WHERE CT.testID = 1 AND 
    CHANGE_TRACKING_IS_COLUMN_IN_MASK(2,CT.SYS_CHANGE_COLUMNS)=1)
        RAISERROR(N&#39;The column VAL was changed&#39;, 10, 1);
        RAISERROR(N&#39;An update conflict has occurred&#39;, 10, 1);
END
COMMIT TRANSACTION&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
  &lt;br /&gt;Change Tracking fits into Microsoft&#39;s &amp;quot;Connect to your data from any device&amp;quot; theme for SQL Server 2008, which is made up of the Microsoft Sync Framework, Sync Services for ADO.Net, SQL Server Compact Edition 3.5. It provides for conflict detection and easy data retrieval of changes with minimum performance impact, and automatic setting for data retention. There are several advantages, such as no schema changes on the tracked tables (no need for a timestamp column), security is at the table level and prevention of loopbacks is easy.&lt;/p&gt;

&lt;p&gt;As always, please leave your comments or send email to &lt;a href=&quot;mailto:sql.slinger@gmail.com&quot;&gt;sql.slinger@gmail.com&lt;/a&gt;. I&#39;m always interested in your feedback.&lt;/p&gt;

&lt;p&gt;Until next time, happy slinging.&lt;/p&gt;

&lt;div class=&quot;wlWriterSmartContent&quot; id=&quot;scid:0767317B-992E-4b12-91E0-4F059A8CECA8:4336937e-a213-4fbe-864b-a38e52648fd2&quot; style=&quot;padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px&quot;&gt;Technorati Tags: &lt;a href=&quot;http://technorati.com/tags/SQL%20Server&quot; rel=&quot;tag&quot;&gt;SQL Server&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/SQL%20Server%202008&quot; rel=&quot;tag&quot;&gt;SQL Server 2008&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Change%20Tracking&quot; rel=&quot;tag&quot;&gt;Change Tracking&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Versioning&quot; rel=&quot;tag&quot;&gt;Versioning&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Version&quot; rel=&quot;tag&quot;&gt;Version&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Row%20Version&quot; rel=&quot;tag&quot;&gt;Row Version&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Tracking&quot; rel=&quot;tag&quot;&gt;Tracking&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Conflict%20Resolution&quot; rel=&quot;tag&quot;&gt;Conflict Resolution&lt;/a&gt;&lt;/div&gt;  &lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script expr:src=&#39;&quot;http://feeds.feedburner.com/~s/SlingingSql?i=&quot; + data:post.url&#39; type=&quot;text/javascript&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;&lt;/div&gt;</description><link>http://sqlslinger.blogspot.com/2008/11/change-tracking-not-cdc.html</link><author>noreply@blogger.com (Dan Ward)</author><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6367058912647240061.post-4114932059085761005</guid><pubDate>Fri, 31 Oct 2008 16:16:00 +0000</pubDate><atom:updated>2008-11-18T11:18:40.980-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Audit</category><category domain="http://www.blogger.com/atom/ns#">Auditing</category><category domain="http://www.blogger.com/atom/ns#">CDC</category><category domain="http://www.blogger.com/atom/ns#">Change Data</category><category domain="http://www.blogger.com/atom/ns#">Change Data Capture</category><category domain="http://www.blogger.com/atom/ns#">History</category><category domain="http://www.blogger.com/atom/ns#">T-SQL</category><category domain="http://www.blogger.com/atom/ns#">Tracking</category><title>Beyond Auditing</title><description>&lt;p&gt;Sometimes capturing the fact that someone changed something and who that someone is, isn&#39;t enough. Sometimes, if the values in a row of a table were changed, you need to know what the original values were along with who changed them. Into this space we introduce SQL Server 2008 Change Data Capture (CDC).    &lt;br /&gt;This new feature of SQL Server records Data Modification Language operations (INSERT, UPDATE, DELETE) on user tables. The changes are exposed using table-valued functions. The CDC asynchronously reads changes in the source tables from the transaction log and inserts those changes into separate change tables. This feature is available in Enterprise, Developer, and Evaluation editions only.&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVccZJW0I1W8K1gOB7PMuqVKwd6Q2C-0q9x6kjq7GRyFPbZX360GYVteQT8PjuFkomdlgJ-FkQcqXROQwnL0cXHYWllDRrV1BryQL4pzDY7PgvJkW_kBIsDvXZAMYEdJIgc84DKQZzFjM/s1600-h/CDC%20Diagram%5B3%5D.png&quot;&gt;&lt;img style=&quot;border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px&quot; height=&quot;328&quot; alt=&quot;CDC Diagram&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEih1L_ovrEfiHCEgWkPWsSfhTSwnqBhia9KwnIRJbrK_SbWq9t82eAMaMyrQpKlnmyESKjOGwLowJAHfcBn7uaiKM1TTx5Q4kjcdHN7PQv1WAe-hUDgEiGRtpgh-e2ZT51gt4VHbqvZ6cc/?imgmax=800&quot; width=&quot;425&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Before we can use this feature we have to configure the database for it. A member of the sysadmin server role must enable CDC on the database by running the sys.sp_cdc_enable_db stored procedure. You can also enable CDC for individual tables only by running sys.sp_cdc_enable_db_change_data_capture.&lt;/p&gt;  &lt;div&gt;   &lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;--First, let&#39;s create a demonstration database with a table in it
USE [master];
GO
IF NOT EXISTS (SELECT name FROM sys.databases WHERE name = N&#39;DemoDB&#39;)
    CREATE DATABASE [MyDB];
GO
USE [MyDB];
GO
CREATE TABLE MyTable
(MyID INT PRIMARY KEY NOT NULL,
 MyItem VARCHAR(128),
 MyQty INT);
 GO
 
--Next, let&#39;s enable CDC on the database
EXEC sys.sp_cdc_enable_db;
GO
--Enable CDC for the Products tableEXEC sys.sp_cdc_enable_table
@source_schema = N&#39;dbo&#39;,
@source_name   = N&#39;MyTable&#39;,
@role_name     = NULL,
@capture_instance = N&#39;MyTbl_1&#39;,
@captured_column_list = N&#39;MyID, MyItem, MyQty&#39;,
@filegroup_name = N&#39;PRIMARY&#39;,
@supports_net_changes = 1
GO&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
  &lt;br /&gt;When you run the two system stored procedures you will see results like these;&lt;/p&gt;

&lt;div&gt;
  &lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;Job &lt;font color=&quot;#000000&quot;&gt;&lt;span style=&quot;color: #006080&quot;&gt;&#39;&lt;font color=&quot;#000000&quot;&gt;cdc.MyDB_capture&lt;/font&gt;&#39;&lt;/span&gt; started successfully.
Job &lt;span style=&quot;color: #006080&quot;&gt;&#39;&lt;font color=&quot;#000000&quot;&gt;cdc.MyDB_cleanup&lt;/font&gt;&#39;&lt;/span&gt;&lt;/font&gt; started successfully.&lt;/pre&gt;
&lt;/div&gt;

&lt;br /&gt;Notice that two jobs are created to monitor/capture and to cleanup the data capture tables. 

&lt;br /&gt;Now, we have our table, let&#39;s put some data into it and modify that data so we can see CDC in action. 

&lt;br /&gt;

&lt;br /&gt;

&lt;div&gt;
  &lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;&lt;p&gt;--Now let&#39;s add some initial data
INSERT INTO MyTable(MyID,MyItem,MyQty) 
Values(1,&#39;Item 1&#39;,20),(2,&#39;Item 2&#39;,10),(3,&#39;Item 3&#39;,1),(4,&#39;Item 4&#39;,3);
GO--And change it&lt;/p&gt;&lt;p&gt;UPDATE MyTable SET MyQty+=10 WHERE MyID=1;
GO



Command(s) completed successfully.&lt;/p&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;br /&gt;Now, when we enabled CDC for the database and the table in it, SQL Server created a pair of Table Valued Functions for us. The functions are named as cdc.fn_get_all_changes_&lt;b&gt;&#39;&lt;/b&gt;&lt;i&gt;capture_instance&lt;/i&gt;&#39;, where &lt;b&gt;&#39;&lt;/b&gt;&lt;i&gt;capture_instance&lt;/i&gt;&#39; is the value we specified for @capture_instance in our sp call to enable cdc on the table. In our case they are cdc.fn_cdc_get_all_changes_MyTbl_1. There are also several built-in functions for CDC that make querying information about CDC tables and instances easier. (See BOL for details). We will use two of the built-in functions in our example below. 

&lt;br /&gt;Here they are in action; 

&lt;br /&gt;

&lt;div&gt;
  &lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;DECLARE @from_lsn binary(10), @to_lsn binary(10);
SELECT @from_lsn = sys.fn_cdc_get_min_lsn(N&#39;MyTbl_1&#39;);
SELECT @to_lsn = sys.fn_cdc_get_max_lsn();
SELECT * FROM cdc.fn_cdc_get_all_changes_MyTbl_1(@from_lsn,@to_lsn,N&#39;all&#39;);
SELECT * FROM cdc.fn_cdc_get_net_changes_MyTbl_1(@from_lsn,@to_lsn,N&#39;all&#39;);
GO&lt;/pre&gt;
&lt;/div&gt;

&lt;br /&gt;And the results from the above query; 

&lt;br /&gt;&amp;#160;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjreyQ63deGkZV4k-wOileE6LZmMfz5cMe4oAeb09EPekVQmjTggXoCMU_OAX8Iqmq1qLUwp6q9DGNgw8FjaghJujhFkWt5RNJBJkV0ojher8AUKZOL7tjelSmBLpupPuQznRoNUWv9hUA/s1600-h/image%5B13%5D.png&quot;&gt;&lt;img style=&quot;border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px&quot; height=&quot;191&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUpMCaYi4F79yMAlpPDahnQXtuXfKpna6BCejZ1vVL1-xDiUWp56q1UH0xlE0yTTfIb7ug0EE64fjXBKL8D7OMTPxa8i5zyhqFCzek-NLurvdEMQ7prYF-ax3AAgzwkoOxFeKcwGmblqw/?imgmax=800&quot; width=&quot;439&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; 

&lt;br /&gt;Notice the difference in the results from the two functions. The first function tracks history for every row in the table. It shows Item 1 as it was insert and again after it&#39;s update. The second function however, doesn&#39;t show the history, but just the net changes. Notice that the initial insert value for Item 1 is missing, only the current value is shown. 

&lt;br /&gt;

&lt;br /&gt;To read more on this topic check out the section in SQL Server 2008 Books Online. See all the available system functions associated with it. BOL topic is Change Data Capture. 

&lt;br /&gt;

&lt;br /&gt;Until next time, happy slinging. 

&lt;br /&gt;

&lt;br /&gt;

&lt;div class=&quot;wlWriterSmartContent&quot; id=&quot;scid:0767317B-992E-4b12-91E0-4F059A8CECA8:0155a56c-8894-42a1-98c9-395f618b6876&quot; style=&quot;padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px&quot;&gt;Technorati Tags: &lt;a href=&quot;http://technorati.com/tags/SQL%20Server%202008&quot; rel=&quot;tag&quot;&gt;SQL Server 2008&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/CDC&quot; rel=&quot;tag&quot;&gt;CDC&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Change%20Data%20Capture&quot; rel=&quot;tag&quot;&gt;Change Data Capture&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Auditing&quot; rel=&quot;tag&quot;&gt;Auditing&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Audit&quot; rel=&quot;tag&quot;&gt;Audit&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Tracking&quot; rel=&quot;tag&quot;&gt;Tracking&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/T-SQL&quot; rel=&quot;tag&quot;&gt;T-SQL&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Database%20audit&quot; rel=&quot;tag&quot;&gt;Database audit&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/database%20tracking&quot; rel=&quot;tag&quot;&gt;database tracking&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/change%20tracking&quot; rel=&quot;tag&quot;&gt;change tracking&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/data%20history&quot; rel=&quot;tag&quot;&gt;data history&lt;/a&gt;&lt;/div&gt;

&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot; charset=&quot;utf-8&quot; expr:src=&quot;&quot; http://feeds.feedburner.com/~s/SlingingSql?i=&quot; + data:post.url&quot;&gt;&lt;/script&gt;&lt;/div&gt;  &lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script expr:src=&#39;&quot;http://feeds.feedburner.com/~s/SlingingSql?i=&quot; + data:post.url&#39; type=&quot;text/javascript&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;&lt;/div&gt;</description><link>http://sqlslinger.blogspot.com/2008/10/beyond-auditing.html</link><author>noreply@blogger.com (Dan Ward)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEih1L_ovrEfiHCEgWkPWsSfhTSwnqBhia9KwnIRJbrK_SbWq9t82eAMaMyrQpKlnmyESKjOGwLowJAHfcBn7uaiKM1TTx5Q4kjcdHN7PQv1WAe-hUDgEiGRtpgh-e2ZT51gt4VHbqvZ6cc/s72-c?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6367058912647240061.post-562403687999449822</guid><pubDate>Thu, 31 Jul 2008 15:57:00 +0000</pubDate><atom:updated>2008-07-31T13:10:01.113-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Managment</category><category domain="http://www.blogger.com/atom/ns#">Managment Studio</category><category domain="http://www.blogger.com/atom/ns#">SQL Server 2008</category><category domain="http://www.blogger.com/atom/ns#">SSMS</category><category domain="http://www.blogger.com/atom/ns#">T-SQL</category><category domain="http://www.blogger.com/atom/ns#">Tools</category><title>Productivity enhancements for SSMS</title><description>&lt;p&gt;SQL Server 2008 includes several enhancements geared toward improving productivity and customer satisfaction. Some of the enhancements have been long sought after by the SQL Server database developer and administrator.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;IntelliSense!      &lt;br /&gt;&lt;/strong&gt;Yes we have long awaited the ability to write T-SQL code with IntelliSense helping code faster. IntelliSense with SQL 08 provides word completion and displays parameter information for functions and stored procs. In the XML editor, IntelliSense can completely show an element declaration. It also indicates errors with red squiggly lines and references them in the Error List window, so you can quickly navigate to the error line by double-clicking the entry. IntelliSense is provided in the Query editor as well as the XML editor, and supports most, but not all, T-SQL syntax. Below are some screen-shots of IntelliSense at work.&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;http://lh5.ggpht.com/dan.w.jr/SJHfFjKt8BI/AAAAAAAAACk/IFwMyQxGqVg/s1600-h/SQL08IntelliSenseMix8.png&quot;&gt;&lt;img style=&quot;border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px&quot; height=&quot;823&quot; alt=&quot;SQL08IntelliSenseMix&quot; src=&quot;http://lh4.ggpht.com/dan.w.jr/SJHfTXGRouI/AAAAAAAAACo/7hfiZXUPfc0/SQL08IntelliSenseMix_thumb8.png?imgmax=800&quot; width=&quot;417&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Collapsible Regions&lt;/strong&gt;&amp;#160; &lt;br /&gt;Similar functionality is now provided in the SMS08 Query Editor to regions delimited by BEGIN...END blocks and multi-line statements, such as SELECT statements that span two or more lines. This is similar to what Visual Studio has offered for a few releases now. Here&#39;s an example (note the &#39;-&#39; sign on the left, click to collapse text):&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;http://lh4.ggpht.com/dan.w.jr/SJHfV6zPCXI/AAAAAAAAACs/ICGvH4uIAyc/s1600-h/SQL08Regions2.png&quot;&gt;&lt;img style=&quot;border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px&quot; height=&quot;51&quot; alt=&quot;SQL08Regions&quot; src=&quot;http://lh5.ggpht.com/dan.w.jr/SJHfaMuLTZI/AAAAAAAAACw/sOu6tUt4er4/SQL08Regions_thumb2.png?imgmax=800&quot; width=&quot;438&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Delimiter Matching&lt;/strong&gt;     &lt;br /&gt;Also similar to Visual Studio, SQL Server 2008 Management Studio now offers delimiter matching and highlighting. When you finish typing the second delimiter in a pair, the editor will highlight both the delimiters, or you can press CTRL + ] to jump to the matching delimiter when you are on one of them. This will help you keep track of parenthesis&#39; and nested blocks. Automatic delimiting will recognize these delimiters;     &lt;br /&gt;&lt;strong&gt;(&lt;/strong&gt;...&lt;strong&gt;)&lt;/strong&gt;, &lt;strong&gt;BEGIN&lt;/strong&gt;...&lt;strong&gt;END&lt;/strong&gt;, &lt;strong&gt;BEGIN&lt;/strong&gt;...&lt;strong&gt;END TRY&lt;/strong&gt;, &lt;strong&gt;BEGIN&lt;/strong&gt;...&lt;strong&gt;END CATCH&lt;/strong&gt;. Brackets and quotes are not recognized for delimiter highlighting.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;SMS Object Explorer      &lt;br /&gt;&lt;/strong&gt;More context menu choices have been provided for your right-click menu in Object Explorer. These choice include options for changing table design, to opening the table with a certain number of returning records, to getting some of the new reports available. Options for partitioning (Storage), Policies, and Indexing are provided as well.&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;http://lh4.ggpht.com/dan.w.jr/SJHfc3qXB7I/AAAAAAAAAC0/9y00zMVuwr0/s1600-h/SQL08SMS13.png&quot;&gt;&lt;img style=&quot;border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px&quot; height=&quot;388&quot; alt=&quot;SQL08SMS1&quot; src=&quot;http://lh5.ggpht.com/dan.w.jr/SJHg2wYIMDI/AAAAAAAAAC4/zUgqqu8KkKU/SQL08SMS1_thumb3.png?imgmax=800&quot; width=&quot;291&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;You will notice a new &amp;quot;Start PowerShell&amp;quot; option. Look for a future post to cover the new Windows PowerShell integration.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Integrated T-SQL Debugging&lt;/strong&gt;    &lt;br /&gt;Debugging has now been integrated into the Query Editor! You can set breakpoints, step through code, step into code a particular location, and even set watches up to monitor variable values, locals and the call stack. Woohoo!!!!&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Other improvements&lt;/strong&gt;    &lt;br /&gt;&lt;em&gt;&lt;u&gt;Multi-Server queries&lt;/u&gt;&lt;/em&gt;, allow you to run a query across numerous servers and return the results with the server name prepended.    &lt;br /&gt;&lt;em&gt;&lt;u&gt;Launch SQL Profiler directly from Management Studio&lt;/u&gt;.      &lt;br /&gt;&lt;u&gt;Customizable tabs&lt;/u&gt;&lt;/em&gt;, allow you to modify the information shown and the layout from the tools\options dialog.    &lt;br /&gt;&lt;em&gt;&lt;u&gt;Object Explorer Detail Pane&lt;/u&gt;&lt;/em&gt; has been improved for better functionality and productivity with navigational improvements, detailed object information pane at the bottom, and integrated object search.    &lt;br /&gt;&lt;em&gt;&lt;u&gt;Object Search&lt;/u&gt;&lt;/em&gt;, allow you to search within a database on a full or partial string match and return objects to the Object Explorer Details pane.    &lt;br /&gt;&lt;em&gt;&lt;u&gt;Activity Monitor&lt;/u&gt;&lt;/em&gt;, you have to see it to appreciate it. Built brand new from scratch, it is based on the Windows Resource Monitor and allows you to see graphs of processor wait time, waiting processes, database I/O and batch requests. Detail grids are provided for Processes, Resource Waits, Data File I/O, and Recent Expensive Queries. It&#39;s a vast improvement for the DBA.    &lt;br /&gt;&lt;em&gt;&lt;u&gt;Performance Studio&lt;/u&gt;,&lt;/em&gt; new performance tuning tool that tracks historical performance metrics and stores them using drill-through reports.    &lt;br /&gt;&lt;em&gt;&lt;u&gt;Partitioning Setup GUI&lt;/u&gt;&lt;/em&gt;, at last a way to create and manage table partitions graphically. This is accessed from the context menu for a table under Storage. A wizard will launch allowing you to create or manage partitions.    &lt;br /&gt;&lt;em&gt;&lt;u&gt;Service Broker Hooks&lt;/u&gt;&lt;/em&gt;, new context menu items centralize access to the Service Broker T-SQL templates for messages, contracts, queues, etc. Read only property pages are provided for each of these objects as well.&lt;/p&gt;  &lt;p&gt;The improvements in the toolset provided with SQL Server 2008 are vast and far sweeping. There are more for you to discover and the best way is to get your hands on it. You can download SQL Server Express 2008 from Microsoft if you don&#39;t have a developers edition license.&lt;/p&gt;  &lt;p&gt;Please, as always, post your comments and questions. Until next time, happy slinging.&lt;/p&gt;  &lt;div class=&quot;wlWriterSmartContent&quot; id=&quot;scid:0767317B-992E-4b12-91E0-4F059A8CECA8:65ff90bf-f4de-43b9-9dc2-2c9dae173997&quot; style=&quot;padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px&quot;&gt;Technorati Tags: &lt;a href=&quot;http://technorati.com/tags/SQL%20Server%202008&quot; rel=&quot;tag&quot;&gt;SQL Server 2008&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/SQL%20Server&quot; rel=&quot;tag&quot;&gt;SQL Server&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/SSMS&quot; rel=&quot;tag&quot;&gt;SSMS&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/SMS&quot; rel=&quot;tag&quot;&gt;SMS&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/SQL%20Server%20Management%20Studio&quot; rel=&quot;tag&quot;&gt;SQL Server Management Studio&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/T-SQL&quot; rel=&quot;tag&quot;&gt;T-SQL&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Query%20Editor&quot; rel=&quot;tag&quot;&gt;Query Editor&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Enhancments&quot; rel=&quot;tag&quot;&gt;Enhancments&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Object%20Explorer&quot; rel=&quot;tag&quot;&gt;Object Explorer&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Object%20Explorer%20Detail%20view&quot; rel=&quot;tag&quot;&gt;Object Explorer Detail view&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Results%20Grid&quot; rel=&quot;tag&quot;&gt;Results Grid&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Activity%20Monitor&quot; rel=&quot;tag&quot;&gt;Activity Monitor&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/SQL%20Tool%20Enhancemenets.&quot; rel=&quot;tag&quot;&gt;SQL Tool Enhancemenets.&lt;/a&gt;&lt;/div&gt;  &lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script expr:src=&#39;&quot;http://feeds.feedburner.com/~s/SlingingSql?i=&quot; + data:post.url&#39; type=&quot;text/javascript&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;&lt;/div&gt;</description><link>http://sqlslinger.blogspot.com/2008/07/productivity-enhancements-for-sms.html</link><author>noreply@blogger.com (Dan Ward)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/dan.w.jr/SJHfTXGRouI/AAAAAAAAACo/7hfiZXUPfc0/s72-c/SQL08IntelliSenseMix_thumb8.png?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6367058912647240061.post-1230306490009076530</guid><pubDate>Wed, 30 Jul 2008 13:51:00 +0000</pubDate><atom:updated>2008-11-18T13:58:09.133-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Audit</category><category domain="http://www.blogger.com/atom/ns#">Auditing</category><category domain="http://www.blogger.com/atom/ns#">Enhanced Events</category><title>Auditing, Katmai Style</title><description>&lt;p&gt;Ok, once again I&#39;ve been unable to keep up with daily posts, so I&#39;ve decided to stop fighting it. Since I&#39;ll most likely never be able to consistently post daily, I&#39;m going to quit worrying about it and just focus on posting good content as I can.&lt;/p&gt;  &lt;p&gt;In this installment though, let&#39;s explore the new Audit feature included in SQL Server 2008. SQL Server 2005 provided auditing via SQL Trace, C2 audit model, and DDL Triggers. While these methods are adequate they leave some room for improvement. &lt;/p&gt;  &lt;p&gt;Into that gap steps the SQL Server Audit. This new feature is based on Extended Events and allows you to monitor server-level and database-level events, individually and in groups. The new SQL Server Audit object collects a single instances of the server or database-level actions and groups of actions to be monitored. The Audit object exists at the SQL Server instance level and you can have multiple audit objects per instances.&lt;/p&gt;  &lt;p&gt;There are two specification objects can be included in an Audit object, the Server Audit Specification and the Database Audit Specification. You can only specify one server audit specification per audit, however you can have a database audit specification for each database in the instance. You can also only have a server audit specification or database audit specifications, not both.&lt;/p&gt;  &lt;p&gt;As you can imagine a server audit specification collects information about the server, which are raised by the Extended Events feature. There are several predefined groups of actions, which are events exposed by the database engine, known as audit action groups. These can be included in your server audit specification object within the audit object.&lt;/p&gt;  &lt;p&gt;The database audit specification collects what else but database-level audit actions, which are raised by the Extended Events feature. You can include either groups of actions or single actions to a database audit specification. Again, audit action groups are provided as predefined groups of actions.&lt;/p&gt;  &lt;p&gt;So, we can collect all this audit information, now what? Well, obviously this feature wouldn&#39;t be complete without the ability to record the information somewhere. This is where the audit target comes into play. Each audit object sends the audit results to a target. That target can be a file, the Windows Security event log, or the Windows Application event log. Note that writing to the Windows Security event log requires elevated permissions, so in order for audit results to be logged there, the SQL Server service account will have to be granted the &amp;quot;Generate security audits&amp;quot; permission in the group or local policy.&lt;/p&gt;  &lt;p&gt;The process of creating and using a SQL Server Audit is as follows;    &lt;br /&gt;1. Create a SQL Server Audit object     &lt;br /&gt;2. Create either a server audit specification or a database audit specification and map it to the audit object.     &lt;br /&gt;3. By default the Audit and Specification objects are disabled, so in this step enable them.     &lt;br /&gt;4. Auditing occurs and&amp;#160; you can read the data in the target you defined as part of the Audit object.&lt;/p&gt;  &lt;p&gt;Let&#39;s see an example:&lt;/p&gt;  &lt;div&gt;   &lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;&lt;p&gt;USE master
GO

--Create the audit object&lt;/p&gt;&lt;p&gt;CREATE SERVER AUDIT SrvAudit TO APPLICATION_LOG;
GO

--Create the audit specification object&lt;/p&gt;&lt;p&gt;CREATE SERVER AUDIT SPECIFICATION AuditSpec
--and map it to the audit object&lt;/p&gt;&lt;p&gt;FOR SERVER AUDIT SrvAudit
--then add the audit action group
ADD (FAILED_LOGIN_GROUP);
GO

--Enable the audit
ALTER SERVER AUDIT SrvAudit WITH (STATE = ON);
GO&lt;/p&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
  &lt;br /&gt;So looking at our Application log after attempting to log in with invalid credentials we see: 

  &lt;br /&gt;&lt;a href=&quot;http://lh4.ggpht.com/dan.w.jr/SJBw00c4ALI/AAAAAAAAAB8/DDqjHIXFTiA/s1600-h/ApplicationLogKatmaiAuditExample%5B3%5D.png&quot;&gt;&lt;img style=&quot;border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px&quot; height=&quot;218&quot; alt=&quot;ApplicationLogKatmaiAuditExample&quot; src=&quot;http://lh6.ggpht.com/dan.w.jr/SJBw4ykyaDI/AAAAAAAAACA/zFCj9vV4n8E/ApplicationLogKatmaiAuditExample_thumb%5B3%5D.png?imgmax=800&quot; width=&quot;435&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(Details) 
  &lt;br /&gt;&lt;a href=&quot;http://lh5.ggpht.com/dan.w.jr/SJBxqlTizRI/AAAAAAAAACc/ybltiFfLFMk/s1600-h/AppLogKatmaiAuditDetailExample%5B3%5D.png&quot;&gt;&lt;img style=&quot;border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px&quot; height=&quot;382&quot; alt=&quot;AppLogKatmaiAuditDetailExample&quot; src=&quot;http://lh5.ggpht.com/dan.w.jr/SJBx1tOyBkI/AAAAAAAAACg/zzRg0zs6EkM/AppLogKatmaiAuditDetailExample_thumb%5B3%5D.png?imgmax=800&quot; width=&quot;342&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For more information about auditing in SQL Server 2008 check out the SQL Server 2008 BOL, topic Auditing.&lt;/p&gt;

&lt;p&gt;Next time we&#39;ll look into some of the IDE and configuration tool enhancements. Until then, keep slinging. &lt;/p&gt;

&lt;div class=&quot;wlWriterSmartContent&quot; id=&quot;scid:0767317B-992E-4b12-91E0-4F059A8CECA8:a8add3cf-9f71-4cbf-8d77-9774a3135a15&quot; style=&quot;padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px&quot;&gt;Technorati Tags: &lt;a href=&quot;http://technorati.com/tags/SQL%20Server%202008&quot; rel=&quot;tag&quot;&gt;SQL Server 2008&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/SQL%20Server&quot; rel=&quot;tag&quot;&gt;SQL Server&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Auditing&quot; rel=&quot;tag&quot;&gt;Auditing&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Event%20Log&quot; rel=&quot;tag&quot;&gt;Event Log&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Enhanced%20Event%20feauture&quot; rel=&quot;tag&quot;&gt;Enhanced Event feauture&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Server%20audit&quot; rel=&quot;tag&quot;&gt;Server audit&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Database%20audit&quot; rel=&quot;tag&quot;&gt;Database audit&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/database&quot; rel=&quot;tag&quot;&gt;database&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/RDBMS&quot; rel=&quot;tag&quot;&gt;RDBMS&lt;/a&gt;&lt;/div&gt;

&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot; charset=&quot;utf-8&quot; expr:src=&quot;&quot; http://feeds.feedburner.com/~s/SlingingSql?i=&quot; + data:post.url&quot;&gt;&lt;/script&gt;&lt;/div&gt;  &lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script expr:src=&#39;&quot;http://feeds.feedburner.com/~s/SlingingSql?i=&quot; + data:post.url&#39; type=&quot;text/javascript&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;&lt;/div&gt;</description><link>http://sqlslinger.blogspot.com/2008/07/auditing-katmai-style.html</link><author>noreply@blogger.com (Dan Ward)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/dan.w.jr/SJBw4ykyaDI/AAAAAAAAACA/zFCj9vV4n8E/s72-c/ApplicationLogKatmaiAuditExample_thumb%5B3%5D.png?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6367058912647240061.post-1729126020929340322</guid><pubDate>Tue, 15 Jul 2008 16:22:00 +0000</pubDate><atom:updated>2008-11-18T14:13:04.083-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Data Types</category><category domain="http://www.blogger.com/atom/ns#">SQL Server 2008</category><category domain="http://www.blogger.com/atom/ns#">T-SQL</category><title>New Data Types</title><description>&lt;p&gt;Well, I managed to miss yesterday, again, so I&#39;m sorry. Luckily, it was only one day, so we aren&#39;t falling into a rut yet.&lt;/p&gt;  &lt;p&gt;Today I&#39;d like to look at the new data types available in SQL Server 2008. Specifically the new Date and Time, Filestream, and the spatial data storage types.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font size=&quot;2&quot;&gt;Date and Time        &lt;br /&gt;&lt;/font&gt;&lt;/strong&gt;The new date/time types are a result of improvements that satisfy the requirements of separating date and time values, allowing a larger range or dates, allowing larger fractional second precision, providing Time zone awareness, providing ANSI SQL compliant or equivalent time and date data types, and to allow database migration compatibility with other database platforms.     &lt;br /&gt;The new types that allow these requirements to be met are:&lt;/p&gt;  &lt;table cellspacing=&quot;0&quot; cellpadding=&quot;2&quot; width=&quot;423&quot; border=&quot;0&quot;&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign=&quot;top&quot; width=&quot;112&quot;&gt;&lt;font size=&quot;1&quot;&gt;&lt;em&gt;&lt;strong&gt;DATE&lt;/strong&gt;&lt;/em&gt; &lt;/font&gt;&lt;/td&gt;        &lt;td valign=&quot;top&quot; width=&quot;307&quot;&gt;&lt;font size=&quot;1&quot;&gt;Stores only the date portion of a date/time and has a range of 0001-01-01 through 9999-12-31. It has a size of 3 bytes.&lt;/font&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign=&quot;top&quot; width=&quot;112&quot;&gt;&lt;strong&gt;&lt;em&gt;&lt;font size=&quot;1&quot;&gt;TIME(prec)&lt;/font&gt;&lt;/em&gt;&lt;/strong&gt;&lt;/td&gt;        &lt;td valign=&quot;top&quot; width=&quot;307&quot;&gt;&lt;font size=&quot;1&quot;&gt;Stores on the time portion of a date/time and has a range of 00:00:00.0000000 through 23:59:59.9999999, an accuracy of 100 nanoseconds (precision dependant). It has a size of 3 to 5 bytes dependant on precision.&lt;/font&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign=&quot;top&quot; width=&quot;112&quot;&gt;&lt;em&gt;&lt;strong&gt;&lt;font size=&quot;1&quot;&gt;DATETIMEOFFSET(prec)&lt;/font&gt;&lt;/strong&gt;&lt;/em&gt;&lt;/td&gt;        &lt;td valign=&quot;top&quot; width=&quot;307&quot;&gt;&lt;font size=&quot;1&quot;&gt;Stores a time zone aware, UTC preserved datetime, and has a range of 0001-01-01 00:00:00.0000000 through 9999-12-31 23:59:59.9999999 UTC. It has a size of 8 to 10 bytes, dependant on&amp;#160; precision&lt;/font&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign=&quot;top&quot; width=&quot;112&quot;&gt;&lt;strong&gt;&lt;em&gt;&lt;font size=&quot;1&quot;&gt;DATETIME2(prec)&lt;/font&gt;&lt;/em&gt;&lt;/strong&gt;&lt;/td&gt;        &lt;td valign=&quot;top&quot; width=&quot;307&quot;&gt;&lt;font size=&quot;1&quot;&gt;Stores datetime data, similar to datetime data type, but with a far larger range. Range is 0001-01-01 00:00:00.0000000 through 9999-12-31 59:59:59.9999999. This data type is not time zone aware and the size is 6 to 8 bytes dependant on precision.&lt;/font&gt;&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;Along with the new data types, new system functions are also provided:&lt;/p&gt; &lt;font size=&quot;1&quot;&gt;   &lt;table cellspacing=&quot;0&quot; cellpadding=&quot;2&quot; width=&quot;423&quot; border=&quot;0&quot;&gt;&lt;tbody&gt;       &lt;tr&gt;         &lt;td valign=&quot;top&quot; width=&quot;163&quot;&gt;&lt;strong&gt;&lt;em&gt;SYSDATETIME()&lt;/em&gt;&lt;/strong&gt;&lt;/td&gt;          &lt;td valign=&quot;top&quot; width=&quot;256&quot;&gt;Returns the current database system timestamp as a datetime2(7) value.&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign=&quot;top&quot; width=&quot;163&quot;&gt;&lt;strong&gt;&lt;em&gt;SYSDATETIMEOFFSET()&lt;/em&gt;&lt;/strong&gt;&lt;/td&gt;          &lt;td valign=&quot;top&quot; width=&quot;256&quot;&gt;Returns the current database system timestamp as a datetimeoffset(7) value.&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign=&quot;top&quot; width=&quot;163&quot;&gt;&lt;strong&gt;&lt;em&gt;SYSUTCDATETIME()&lt;/em&gt;&lt;/strong&gt;&lt;/td&gt;          &lt;td valign=&quot;top&quot; width=&quot;256&quot;&gt;Returns the current database system timestamp as a datetime2(7) value, which represents the current UTC time.&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign=&quot;top&quot; width=&quot;163&quot;&gt;&lt;strong&gt;&lt;em&gt;SWITCHOFFSET(datetimeoffset, time_zone)&lt;/em&gt;&lt;/strong&gt;&lt;/td&gt;          &lt;td valign=&quot;top&quot; width=&quot;256&quot;&gt;Converts a datetimeoffset to a new time zone.&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign=&quot;top&quot; width=&quot;163&quot;&gt;&lt;strong&gt;&lt;em&gt;TODATETIMEOFFSET(datetime, time_zone)&lt;/em&gt;&lt;/strong&gt;&lt;/td&gt;          &lt;td valign=&quot;top&quot; width=&quot;256&quot;&gt;Converts a local datetime value to a datetimeoffset UTC value using the passed in time_zone value.&lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;&lt;/table&gt; &lt;/font&gt;  &lt;br /&gt;Let&#39;s look briefly at these new data types in action:   &lt;br /&gt;  &lt;div&gt;   &lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 103.99%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; height: 784px; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;-- Show type usage
DECLARE @DateEx DATE;
DECLARE @TimeEx TIME;
DECLARE @DTOffEx DATETIMEOFFSET(7);
DECLARE @DT2Ex DATETIME2(7);
-- Put in some data
SET @DateEx = &#39;2008-02-28 06:59:01.9489484&#39;;
SET @TimeEx = &#39;2008-02-28 06:59:01.9489484&#39;;
-- View results
SELECT @DateEx AS [Date], @TimeEx AS [Time]
Output:
Date                    Time
----------------------- ----------------
2008-02-28 00:00:00.000 06:59:01.9489484
(1 rows(s) affected)
------------------------------------------------
-- system date and time
SELECT  SYSDATETIME() AS [SysDateTime], 
        SYSDATETIMEOFFSET() AS SYSDTOffset, 
        SYSUTCDATETIME() AS SysUTC;

Output:
SysDateTime             SYSDTOffset                        SysUTC
----------------------- ---------------------------------- -----------------------
2008-07-15 10:49:55.459 7/15/2008 10:49:55 AM -04:00       2008-07-15 14:49:55.459

(1 rows(s) affected)
-- Offset for a date
SELECT DATENAME(TZoffset, &#39;2008-02-28 12:15:32.1234567 +02:10&#39;) AS TZoffset;

Output:
TZoffset
------------------------------
+02:10

(1 rows(s) affected)

--Change the offset
SELECT SWITCHOFFSET (&#39;2008-02-28 9:50:00.6722 -8:00&#39;,&#39;+02:00&#39;) AS Changed

Output:
Changed
----------------------------------
2/28/2008 7:50:00 PM +02:00
(1 rows(s) affected)&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
  &lt;br /&gt;&lt;strong&gt;&lt;font size=&quot;2&quot;&gt;Filestream 
      &lt;br /&gt;&lt;/font&gt;&lt;/strong&gt;The Filestream attribute is a storage feature that combines the windows file system with the SQL Server database. When the Filestream attribute is added to a varbinary(max) column the database storage engine stores the column values in the NTFS file system, but the behavior of the database column will remain the same. 

  &lt;br /&gt;Utilizing this feature allows you to access the data in a dual programming model, in other words, you can access the data view T-SQL as if it were a normal BLOB type, as well as via the Win32 streaming API with T-SQL transactional semantics. 

  &lt;br /&gt;So, when should I use Filestream storage as opposed to good old BLOB storage? If your average value size is going to exceed 1MB and you need fast read access, it is a good idea. Also when you are developing middle tier application services that may need to access this data. 

  &lt;br /&gt;Standard BLOB storage is limited to 2GB size restrictions, however, the Filestream storage is only limited by the file system free space. Since the database engine keeps the column behavior consistent, integrated management is maintained, backups and restores work normally as well as third party management tools. 

  &lt;br /&gt;There are a few drawbacks to using the Filestream feature. Support is not provided for Database Snapshots or Database Mirroring, and encryption does not work with Filestream storage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font size=&quot;2&quot;&gt;Spatial Data Types 
      &lt;br /&gt;&lt;/font&gt;&lt;/strong&gt;With all the pressure from Google providing Google Maps, Google Earth, and other geographical services from various sources, it is no wonder Microsoft has begun to provide Spatial Data Storage support. 

  &lt;br /&gt;SQL Server 2008 provides new data types to handle spatial data. These data types are &lt;strong&gt;Geometry&lt;/strong&gt; and &lt;strong&gt;Geography&lt;/strong&gt;. Both data types are implemented as .Net CLR types, and support various methods and properties. 

  &lt;br /&gt;As the name implies, the &lt;strong&gt;Geometry&lt;/strong&gt; data type is designed to store data specified by coordinates in a 2 dimensional, flat-earth system (Euclidean data). It remains compliant with the Open Geospatial Consortium (OGC) Simple Features for SQL Specification version 1.1.0. 

  &lt;br /&gt;The &lt;strong&gt;Geography&lt;/strong&gt; data type, is similar to the Geometry data type in that it stores coordinates, however, the Geography data type stores coordinates defined by latitude and longitude in a round-earth system. 

  &lt;br /&gt;With the use of new data types we need to be able to efficiently store and search for that data, so SQL Server 2008 provides the new &lt;strong&gt;Spatial Indexes&lt;/strong&gt; to go along with the new data types. These indexes are grid-based and level of the index decomposes the one above it.&lt;/p&gt;

&lt;p&gt;Here is a diagram from BOL that depicts the structure of the spatial data types. 
  &lt;br /&gt;&lt;a href=&quot;http://lh3.ggpht.com/dan.w.jr/SHzOxWnJyBI/AAAAAAAAAB0/YAiA-Y9Cd2c/s1600-h/geometry%20diagram%5B1%5D.png&quot;&gt;&lt;img style=&quot;border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px&quot; height=&quot;189&quot; alt=&quot;geometry diagram&quot; src=&quot;http://lh4.ggpht.com/dan.w.jr/SHzO0wnU8hI/AAAAAAAAAB4/lYeuGU7sYBk/geometry%20diagram_thumb%5B1%5D.png?imgmax=800&quot; width=&quot;427&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See SQL Server 2008 BOL for more detailed information. 
  &lt;br /&gt;Finally, let&#39;s take a peek at this in action:&lt;/p&gt;

&lt;div&gt;
  &lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;-- Make a table to use that holds geography data type
CREATE TABLE SpatialTable 
    ( id int IDENTITY (1,1),
    GeogCol1 geography, 
    GeogCol2 AS GeogCol1.STAsText() );
GO
-- Put some data into the table to use
-- Notice the use of the STGeomFromText 
-- instance method.
INSERT INTO SpatialTable (GeogCol1)
VALUES (geography::STGeomFromText(&#39;LINESTRING(47.656 -122.360, 47.656 -122.343)&#39;, 4326));
INSERT INTO SpatialTable (GeogCol1)
VALUES (geography::STGeomFromText(&#39;POLYGON((47.653 -122.358, 47.649 -122.348, 47.658 -122.348, 47.658 -122.358, 47.653 -122.358))&#39;, 4326));
GO
-- Make some variables
DECLARE @geog1 geography;
DECLARE @geog2 geography;
DECLARE @result geography;
-- Put some data in the variables from the table,
-- notice the use of built in methods/properties
-- of the data type &amp;quot;STAsTex()&amp;quot;
SELECT @geog1 = GeogCol1 FROM SpatialTable WHERE id = 1;
SELECT @geog2 = GeogCol1 FROM SpatialTable WHERE id = 2;
SELECT @result = @geog1.STIntersection(@geog2);
SELECT @result.STAsText();
Output:
------------------------------------------------------------------------------------------
LINESTRING (47.656000260658459 -122.3479999999668, 47.656000130309728 -122.35799999998773)
(1 row(s) affected)
-- Quick example of using the POINT instance
DECLARE @g geometry;
SET @g = geometry::STGeomFromText(&#39;POINT (3 4)&#39;, 0);
SELECT @g
Output:
------------------------------------------------------------------------------------------
0x00000000010C00000000000008400000000000001040
(1 row(s) affected)&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
  &lt;br /&gt;Well, that brings us to the end of another post. I hope you gained something useful from it. I will try really hard to make sure there is a post tomorrow, though I have late meetings this evening so the next entry may be on Thursday. Until then, see you later.&lt;/p&gt;

&lt;div class=&quot;wlWriterSmartContent&quot; id=&quot;scid:0767317B-992E-4b12-91E0-4F059A8CECA8:1d635689-e998-454f-9a55-6a234fec0edc&quot; style=&quot;padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px&quot;&gt;Technorati Tags: &lt;a href=&quot;http://technorati.com/tags/SQL%20Server%202008&quot; rel=&quot;tag&quot;&gt;SQL Server 2008&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/SQL%20Server&quot; rel=&quot;tag&quot;&gt;SQL Server&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/T-SQL&quot; rel=&quot;tag&quot;&gt;T-SQL&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Data%20Types&quot; rel=&quot;tag&quot;&gt;Data Types&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Indexes&quot; rel=&quot;tag&quot;&gt;Indexes&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Spatial%20Data&quot; rel=&quot;tag&quot;&gt;Spatial Data&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Dates&quot; rel=&quot;tag&quot;&gt;Dates&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Times&quot; rel=&quot;tag&quot;&gt;Times&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Time%20Zones&quot; rel=&quot;tag&quot;&gt;Time Zones&lt;/a&gt;&lt;/div&gt;

&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot; charset=&quot;utf-8&quot; expr:src=&quot;&quot; http://feeds.feedburner.com/~s/SlingingSql?i=&quot; + data:post.url&quot;&gt;&lt;/script&gt;&lt;/div&gt;  &lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script expr:src=&#39;&quot;http://feeds.feedburner.com/~s/SlingingSql?i=&quot; + data:post.url&#39; type=&quot;text/javascript&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;&lt;/div&gt;</description><link>http://sqlslinger.blogspot.com/2008/07/new-data-types.html</link><author>noreply@blogger.com (Dan Ward)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/dan.w.jr/SHzO0wnU8hI/AAAAAAAAAB4/lYeuGU7sYBk/s72-c/geometry%20diagram_thumb%5B1%5D.png?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6367058912647240061.post-1390524561919938709</guid><pubDate>Fri, 11 Jul 2008 22:20:00 +0000</pubDate><atom:updated>2008-07-12T18:28:01.982-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Data Types</category><category domain="http://www.blogger.com/atom/ns#">SQL Server 2008</category><category domain="http://www.blogger.com/atom/ns#">T-SQL</category><title>Hierarchy made easier</title><description>&lt;p&gt;Well, we are on a roll now, three days in a row! Today let&#39;s examine some new data types that have been added to SQL Server 2008.&lt;/p&gt;  &lt;p&gt;SQL Server 2008 offers several new data types. One of the more interesting is the HierarchyID type. The HierarchyID data type is implemented as a CLR UDT (User defined type) and is exposed to CLR clients as SqlHierarchyId. The HierarchyID type will allow you to model organization structures, tree structures and hierarchies.   &lt;br /&gt;This new data type comes with many built-in methods that will allow you to manipulate and edit hierarchical data.     &lt;br /&gt;The methods exposed by the HierarchyID are:&lt;/p&gt;  &lt;table cellspacing=&quot;0&quot; cellpadding=&quot;2&quot; width=&quot;400&quot; border=&quot;0&quot;&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign=&quot;top&quot; width=&quot;400&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;child.GetAncestor(n)&lt;/font&gt; - this returns the HierarchyID of the nth ancestor&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign=&quot;top&quot; width=&quot;400&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;parent.GetDescendant(child1, child2)&lt;/font&gt; - this returns a child node&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign=&quot;top&quot; width=&quot;400&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;node.GetLevel()&lt;/font&gt; - returns an integer value of the depth of the node in the structure&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign=&quot;top&quot; width=&quot;400&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;hierarchyid::GetRoot()&lt;/font&gt; - returns the root of the structure&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign=&quot;top&quot; width=&quot;400&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;parent.IsDescendant(child)&lt;/font&gt; - determines if a node is a descendant of another node&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign=&quot;top&quot; width=&quot;400&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;hierarchyid::Parse(string)&lt;/font&gt; - converts a string representation of a hierarchyid into a hierarchyid value&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign=&quot;top&quot; width=&quot;400&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;void Read(BinaryReader x)&lt;/font&gt; - for CLR clients, reads a binary representation of a SqlHierarchyId object from the BinaryReader parameter and sets the SqlHierarchyId object to that value&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign=&quot;top&quot; width=&quot;400&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;node.Reparent(OldRoot, NewRoot)&lt;/font&gt; - move a node in the hierarchy from one parent to another&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign=&quot;top&quot; width=&quot;400&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;node.ToString()&lt;/font&gt; - returns a string with a logical representation of the node&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign=&quot;top&quot; width=&quot;400&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;void Write(BinaryWriter x)&lt;/font&gt; - for CLR clients, writes a binary representation of a SqlHierarchyId object to the BinaryWriter parameter.&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;You can use any of the above methods that return a node (representation of the hierarchy) in place of HierarchyID data type.   &lt;br /&gt;     &lt;br /&gt;Let&#39;s look at how the HierarchyID works (as seen on Ravi Maniam&#39;s blog (&lt;a href=&quot;http://blogs.msdn.com/manisblog/archive/2007/08/17/sql-server-2008-hierarchyid.aspx&quot;&gt;http://blogs.msdn.com/manisblog/archive/2007/08/17/sql-server-2008-hierarchyid.aspx&lt;/a&gt;);&lt;/p&gt;  &lt;div&gt;   &lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;Use&lt;/span&gt; AdventureWorks
&lt;span style=&quot;color: #0000ff&quot;&gt;Go&lt;/span&gt;  
&lt;font color=&quot;#008000&quot;&gt;--Create Scheme&lt;/font&gt;
&lt;span style=&quot;color: #0000ff&quot;&gt;Create&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;Schema&lt;/span&gt; HumanResources 
&lt;span style=&quot;color: #0000ff&quot;&gt;Go&lt;/span&gt;  
&lt;font color=&quot;#008000&quot;&gt;--&lt;font color=&quot;#008000&quot;&gt;&lt;/font&gt;Create Table &lt;/font&gt; 
&lt;span style=&quot;color: #0000ff&quot;&gt;CREATE&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;TABLE&lt;/span&gt; HumanResources.EmployeeDemo 
( 
OrgNode &lt;font color=&quot;#0000ff&quot;&gt;HIERARCHYID&lt;/font&gt;, 
EmployeeID &lt;span style=&quot;color: #0000ff&quot;&gt;INT&lt;/span&gt;, 
LoginID &lt;span style=&quot;color: #0000ff&quot;&gt;VARCHAR&lt;/span&gt;(100), 
Title &lt;span style=&quot;color: #0000ff&quot;&gt;VARCHAR&lt;/span&gt;(200), 
HireDate &lt;font color=&quot;#0000ff&quot;&gt;DATETIME &lt;/font&gt;
) 
&lt;span style=&quot;color: #0000ff&quot;&gt;Go&lt;/span&gt; 
&lt;font color=&quot;#008000&quot;&gt;--Create Index&lt;/font&gt;
&lt;span style=&quot;color: #0000ff&quot;&gt;CREATE&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;UNIQUE&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;CLUSTERED&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;INDEX&lt;/span&gt; idxEmployeeDemo 
&lt;span style=&quot;color: #0000ff&quot;&gt;ON&lt;/span&gt; HumanResources.EmployeeDemo (OrgNode,EmployeeID) 

&lt;font color=&quot;#008000&quot;&gt;--Insert First Row&lt;/font&gt;       
INSERT HumanResources.EmployeeDemo (OrgNode, EmployeeID, LoginID, Title, HireDate)              
&lt;span style=&quot;color: #0000ff&quot;&gt;VALUES&lt;/span&gt; (hierarchyid.GetRoot(), 1,&lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;adventure-works\scott&#39;&lt;/font&gt;&lt;/span&gt;, &lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;CEO&#39;&lt;/font&gt;&lt;/span&gt;, &lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;3/11/05&#39;&lt;/font&gt;&lt;/span&gt;) ; 
&lt;span style=&quot;color: #0000ff&quot;&gt;Go&lt;/span&gt;           
&lt;font color=&quot;#008000&quot;&gt;--Insert Second Row&lt;/font&gt;      
&lt;span style=&quot;color: #0000ff&quot;&gt;DECLARE&lt;/span&gt; @Manager &lt;font color=&quot;#0000ff&quot;&gt;hierarchyid&lt;/font&gt;            
&lt;span style=&quot;color: #0000ff&quot;&gt;SELECT&lt;/span&gt; @Manager = hierarchyid.GetRoot() &lt;span style=&quot;color: #0000ff&quot;&gt;FROM&lt;/span&gt; HumanResources.EmployeeDemo; 
&lt;font color=&quot;#0000ff&quot;&gt;INSERT&lt;/font&gt; HumanResources.EmployeeDemo (OrgNode, EmployeeID, LoginID, Title, HireDate)              
&lt;span style=&quot;color: #0000ff&quot;&gt;VALUES&lt;/span&gt; (@Manager.GetDescendant(&lt;span style=&quot;color: #0000ff&quot;&gt;NULL&lt;/span&gt;,&lt;span style=&quot;color: #0000ff&quot;&gt;NULL&lt;/span&gt;), 2, &lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;adventure-works\Mark&#39;&lt;/font&gt;&lt;/span&gt;,            
&lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;CTO&#39;&lt;/font&gt;&lt;/span&gt;, &lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;4/05/07&#39;&lt;/font&gt;&lt;/span&gt;)         
&lt;span style=&quot;color: #0000ff&quot;&gt;Go&lt;/span&gt; 
&lt;font color=&quot;#008000&quot;&gt;--Insert Third Row&lt;/font&gt;
&lt;span style=&quot;color: #0000ff&quot;&gt;DECLARE&lt;/span&gt; @Manager &lt;font color=&quot;#0000ff&quot;&gt;hierarchyid            &lt;/font&gt;
&lt;span style=&quot;color: #0000ff&quot;&gt;DECLARE&lt;/span&gt; @FirstChild &lt;font color=&quot;#0000ff&quot;&gt;hierarchyid&lt;/font&gt;         
&lt;span style=&quot;color: #0000ff&quot;&gt;SELECT&lt;/span&gt; @Manager = hierarchyid.GetRoot() &lt;span style=&quot;color: #0000ff&quot;&gt;FROM&lt;/span&gt; HumanResources.EmployeeDemo; 
&lt;span style=&quot;color: #0000ff&quot;&gt;Select&lt;/span&gt; @FirstChild = @Manager.GetDescendant(&lt;span style=&quot;color: #0000ff&quot;&gt;NULL&lt;/span&gt;,&lt;span style=&quot;color: #0000ff&quot;&gt;NULL&lt;/span&gt;)              
INSERT HumanResources.EmployeeDemo (OrgNode, EmployeeID, LoginID, Title, HireDate)              
&lt;span style=&quot;color: #0000ff&quot;&gt;VALUES&lt;/span&gt; (@Manager.GetDescendant(@FirstChild,&lt;span style=&quot;color: #0000ff&quot;&gt;NULL&lt;/span&gt;), 3, &lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;adventure-works\ravi&#39;&lt;/font&gt;&lt;/span&gt;,            
&lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;Director Marketing&#39;&lt;/font&gt;&lt;/span&gt;, &lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;4/08/07&#39;&lt;/font&gt;&lt;/span&gt;)        
&lt;span style=&quot;color: #0000ff&quot;&gt;Go&lt;/span&gt;           
&lt;font color=&quot;#008000&quot;&gt;--Insert the First Descendant of a Child Node&lt;/font&gt;         
&lt;span style=&quot;color: #0000ff&quot;&gt;DECLARE&lt;/span&gt; @Manager &lt;font color=&quot;#0000ff&quot;&gt;hierarchyid&lt;/font&gt;            
&lt;span style=&quot;color: #0000ff&quot;&gt;SELECT&lt;/span&gt; @Manager = &lt;span style=&quot;color: #0000ff&quot;&gt;CAST&lt;/span&gt;(&lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;/1/&#39;&lt;/font&gt;&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;AS&lt;/span&gt; &lt;font color=&quot;#0000ff&quot;&gt;hierarchyid&lt;/font&gt;)          
INSERT HumanResources.EmployeeDemo (OrgNode, EmployeeID, LoginID, Title, HireDate)              
&lt;span style=&quot;color: #0000ff&quot;&gt;VALUES&lt;/span&gt; (@Manager.GetDescendant(&lt;span style=&quot;color: #0000ff&quot;&gt;NULL&lt;/span&gt;, &lt;span style=&quot;color: #0000ff&quot;&gt;NULL&lt;/span&gt;),45,        
&lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;adventure-works\Ben&#39;&lt;/font&gt;&lt;/span&gt;,&lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;Application Developer&#39;&lt;/font&gt;&lt;/span&gt;, &lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;6/11/07&#39;&lt;/font&gt;&lt;/span&gt;) ;         
&lt;span style=&quot;color: #0000ff&quot;&gt;Go&lt;/span&gt;           
&lt;font color=&quot;#008000&quot;&gt;--Insert the Second Descendant of a Child Node&lt;/font&gt;        
&lt;span style=&quot;color: #0000ff&quot;&gt;DECLARE&lt;/span&gt; @Manager &lt;font color=&quot;#0000ff&quot;&gt;hierarchyid&lt;/font&gt;            
&lt;span style=&quot;color: #0000ff&quot;&gt;DECLARE&lt;/span&gt; @FirstChild &lt;font color=&quot;#0000ff&quot;&gt;hierarchyid&lt;/font&gt;         
&lt;span style=&quot;color: #0000ff&quot;&gt;SELECT&lt;/span&gt; @Manager = &lt;span style=&quot;color: #0000ff&quot;&gt;CAST&lt;/span&gt;(&lt;span style=&quot;color: #006080&quot;&gt;&#39;/1/&#39;&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;AS&lt;/span&gt; &lt;font color=&quot;#0000ff&quot;&gt;hierarchyid&lt;/font&gt;)          
&lt;span style=&quot;color: #0000ff&quot;&gt;SELECT&lt;/span&gt; @FirstChild = @Manager.GetDescendant(&lt;span style=&quot;color: #0000ff&quot;&gt;NULL&lt;/span&gt;,&lt;span style=&quot;color: #0000ff&quot;&gt;NULL&lt;/span&gt;)              
INSERT HumanResources.EmployeeDemo (OrgNode, EmployeeID, LoginID, Title, HireDate)              
&lt;span style=&quot;color: #0000ff&quot;&gt;VALUES&lt;/span&gt; (@Manager.GetDescendant(@FirstChild, &lt;span style=&quot;color: #0000ff&quot;&gt;NULL&lt;/span&gt;),55,        
&lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;adventure-works\Laura&#39;&lt;/font&gt;&lt;/span&gt;,&lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;Trainee Developer&#39;&lt;/font&gt;&lt;/span&gt;, &lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;6/11/07&#39;&lt;/font&gt;&lt;/span&gt;) ;           
&lt;span style=&quot;color: #0000ff&quot;&gt;Go&lt;/span&gt;           
&lt;font color=&quot;#008000&quot;&gt;--Insert the first node who is the Descendant of Director&lt;/font&gt; Marketing       
&lt;span style=&quot;color: #0000ff&quot;&gt;DECLARE&lt;/span&gt; @Manager &lt;font color=&quot;#0000ff&quot;&gt;hierarchyid&lt;/font&gt;            
&lt;span style=&quot;color: #0000ff&quot;&gt;DECLARE&lt;/span&gt; @FirstChild &lt;font color=&quot;#0000ff&quot;&gt;hierarchyid&lt;/font&gt;         
&lt;span style=&quot;color: #0000ff&quot;&gt;SELECT&lt;/span&gt; @Manager = &lt;span style=&quot;color: #0000ff&quot;&gt;CAST&lt;/span&gt;(&lt;span style=&quot;color: #006080&quot;&gt;&#39;/2/&#39;&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;AS&lt;/span&gt; &lt;font color=&quot;#0000ff&quot;&gt;hierarchyid&lt;/font&gt;)          
INSERT HumanResources.EmployeeDemo (OrgNode, EmployeeID, LoginID, Title, HireDate)              
&lt;span style=&quot;color: #0000ff&quot;&gt;VALUES&lt;/span&gt; (@Manager.GetDescendant(&lt;span style=&quot;color: #0000ff&quot;&gt;NULL&lt;/span&gt;, &lt;span style=&quot;color: #0000ff&quot;&gt;NULL&lt;/span&gt;),551,              
&lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;adventure-works\frank&#39;&lt;/font&gt;&lt;/span&gt;,&lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;Trainee Sales Exec.&#39;&lt;/font&gt;&lt;/span&gt;, &lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;12/11/07&#39;&lt;/font&gt;&lt;/span&gt;) ;        
&lt;span style=&quot;color: #0000ff&quot;&gt;Go&lt;/span&gt;           
&lt;font color=&quot;#008000&quot;&gt;--Insert the second node who is the Descendant of Director&lt;/font&gt;&lt;font color=&quot;#008000&quot;&gt;&lt;br /&gt;--Marketing&lt;/font&gt;             
&lt;span style=&quot;color: #0000ff&quot;&gt;DECLARE&lt;/span&gt; @Manager &lt;font color=&quot;#0000ff&quot;&gt;hierarchyid&lt;/font&gt;            
&lt;span style=&quot;color: #0000ff&quot;&gt;DECLARE&lt;/span&gt; @FirstChild &lt;font color=&quot;#0000ff&quot;&gt;hierarchyid&lt;/font&gt;         
&lt;span style=&quot;color: #0000ff&quot;&gt;SELECT&lt;/span&gt; @Manager = &lt;span style=&quot;color: #0000ff&quot;&gt;CAST&lt;/span&gt;(&lt;span style=&quot;color: #006080&quot;&gt;&#39;/2/&#39;&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;AS&lt;/span&gt; &lt;font color=&quot;#0000ff&quot;&gt;hierarchyid&lt;/font&gt;)          
&lt;span style=&quot;color: #0000ff&quot;&gt;SELECT&lt;/span&gt; @FirstChild = @Manager.GetDescendant(&lt;span style=&quot;color: #0000ff&quot;&gt;NULL&lt;/span&gt;,&lt;span style=&quot;color: #0000ff&quot;&gt;NULL&lt;/span&gt;)              
INSERT HumanResources.EmployeeDemo (OrgNode, EmployeeID, LoginID, Title, HireDate)              
&lt;span style=&quot;color: #0000ff&quot;&gt;VALUES&lt;/span&gt; (@Manager.GetDescendant(@FirstChild, &lt;span style=&quot;color: #0000ff&quot;&gt;NULL&lt;/span&gt;),531,              
&lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;adventure-works\vijay&#39;&lt;/font&gt;&lt;/span&gt;,&lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;Manager Industrial Sales&#39;&lt;/font&gt;&lt;/span&gt;,&lt;font color=&quot;#ff0000&quot;&gt; &lt;span style=&quot;color: #006080&quot;&gt;&#39;12/09/06&#39;&lt;/span&gt;&lt;/font&gt;) ;         
&lt;span style=&quot;color: #0000ff&quot;&gt;Go&lt;/span&gt;           
&lt;font color=&quot;#008000&quot;&gt;--Insert the third node who is the Descendant of Director &lt;br /&gt;-- Marketing&lt;/font&gt;              
&lt;font color=&quot;#008000&quot;&gt;--in between 2 existing descendants&lt;/font&gt;            
&lt;span style=&quot;color: #0000ff&quot;&gt;DECLARE&lt;/span&gt; @Manager &lt;font color=&quot;#0000ff&quot;&gt;hierarchyid&lt;/font&gt;            
&lt;span style=&quot;color: #0000ff&quot;&gt;DECLARE&lt;/span&gt; @FirstChild &lt;font color=&quot;#0000ff&quot;&gt;hierarchyid&lt;/font&gt;         
&lt;span style=&quot;color: #0000ff&quot;&gt;DECLARE&lt;/span&gt; @SecondChild &lt;font color=&quot;#0000ff&quot;&gt;hierarchyid&lt;/font&gt;        
&lt;span style=&quot;color: #0000ff&quot;&gt;SELECT&lt;/span&gt; @Manager = &lt;span style=&quot;color: #0000ff&quot;&gt;CAST&lt;/span&gt;(&lt;span style=&quot;color: #006080&quot;&gt;&#39;/2/&#39;&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;AS&lt;/span&gt; &lt;font color=&quot;#0000ff&quot;&gt;hierarchyid&lt;/font&gt;)          
&lt;span style=&quot;color: #0000ff&quot;&gt;SELECT&lt;/span&gt; @FirstChild = @Manager.GetDescendant(&lt;span style=&quot;color: #0000ff&quot;&gt;NULL&lt;/span&gt;,&lt;span style=&quot;color: #0000ff&quot;&gt;NULL&lt;/span&gt;)              
&lt;span style=&quot;color: #0000ff&quot;&gt;SELECT&lt;/span&gt; @SecondChild = @Manager.GetDescendant(@FirstChild,&lt;span style=&quot;color: #0000ff&quot;&gt;NULL&lt;/span&gt;)            
INSERT HumanResources.EmployeeDemo (OrgNode, EmployeeID, LoginID, Title, HireDate)              
&lt;span style=&quot;color: #0000ff&quot;&gt;VALUES&lt;/span&gt; (@Manager.GetDescendant(@FirstChild, @SecondChild),543,            
&lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;adventure-works\james&#39;&lt;/font&gt;&lt;/span&gt;,&lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;Manager Consumer Sales&#39;&lt;/font&gt;&lt;/span&gt;, &lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;12/04/06&#39;&lt;/font&gt;&lt;/span&gt;) ;
&lt;font color=&quot;#008000&quot;&gt;--Use Serializable Transaction&lt;/font&gt; 
&lt;span style=&quot;color: #0000ff&quot;&gt;CREATE&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;PROCEDURE&lt;/span&gt; AddEmployee(@ManagerID &lt;font color=&quot;#0000ff&quot;&gt;hierarchyid&lt;/font&gt;, @EmpID &lt;span style=&quot;color: #0000ff&quot;&gt;int&lt;/span&gt;, 
@LogID &lt;span style=&quot;color: #0000ff&quot;&gt;varchar&lt;/span&gt;(100), @JobTitle &lt;span style=&quot;color: #0000ff&quot;&gt;as&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;varchar&lt;/span&gt;(200), @JoiningDate &lt;font color=&quot;#0000ff&quot;&gt;datetime&lt;/font&gt;) 
&lt;span style=&quot;color: #0000ff&quot;&gt;AS&lt;/span&gt; 
&lt;span style=&quot;color: #0000ff&quot;&gt;BEGIN&lt;/span&gt; 
&lt;span style=&quot;color: #0000ff&quot;&gt;DECLARE&lt;/span&gt; @LastChild &lt;font color=&quot;#0000ff&quot;&gt;hierarchyid&lt;/font&gt; 
&lt;span style=&quot;color: #0000ff&quot;&gt;SET&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;TRANSACTION&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;ISOLATION&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;LEVEL&lt;/span&gt; SERIALIZABLE 
&lt;span style=&quot;color: #0000ff&quot;&gt;BEGIN&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;TRANSACTION&lt;/span&gt; 
&lt;span style=&quot;color: #0000ff&quot;&gt;SELECT&lt;/span&gt; @LastChild = &lt;span style=&quot;color: #0000ff&quot;&gt;Max&lt;/span&gt;(OrgNode) &lt;span style=&quot;color: #0000ff&quot;&gt;From&lt;/span&gt; HumanResources.EmployeeDemo 
&lt;span style=&quot;color: #0000ff&quot;&gt;WHERE&lt;/span&gt; OrgNode = @ManagerID 
&lt;font color=&quot;#0000ff&quot;&gt;INSERT&lt;/font&gt; HumanResources.EmployeeDemo (OrgNode, EmployeeID, LoginID, Title, HireDate) 
&lt;span style=&quot;color: #0000ff&quot;&gt;VALUES&lt;/span&gt;(@LastChild, @EmpID,@LogID , @JobTitle, @JoiningDate) 
&lt;span style=&quot;color: #0000ff&quot;&gt;COMMIT&lt;/span&gt; 
&lt;span style=&quot;color: #0000ff&quot;&gt;END&lt;/span&gt; ;&lt;/pre&gt;
&lt;/div&gt;

&lt;div&gt;&amp;#160;&lt;/div&gt;

&lt;div&gt;Please post any questions in the comments and I&#39;ll get back to you quickly. I hope you can find a use for the HierarchyID data type in your day to day work.
  &lt;br /&gt;&lt;/div&gt;

&lt;div&gt;Have a good weekend and we&#39;ll be back on Monday. Remember to post any suggestions for topics or specific questions. You can also email me at &lt;a href=&quot;mailto:sql.slinger@gmail.com&quot;&gt;sql.slinger@gmail.com&lt;/a&gt;.&lt;/div&gt;

&lt;div class=&quot;wlWriterSmartContent&quot; id=&quot;scid:0767317B-992E-4b12-91E0-4F059A8CECA8:5efd36b1-0832-4935-a753-bbac836c8c61&quot; style=&quot;padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px&quot;&gt;Technorati Tags: &lt;a href=&quot;http://technorati.com/tags/SQL%20Server&quot; rel=&quot;tag&quot;&gt;SQL Server&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/SQL%20Server%202008&quot; rel=&quot;tag&quot;&gt;SQL Server 2008&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/T-SQL&quot; rel=&quot;tag&quot;&gt;T-SQL&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Data%20Types&quot; rel=&quot;tag&quot;&gt;Data Types&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Katmai&quot; rel=&quot;tag&quot;&gt;Katmai&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/Microsoft&quot; rel=&quot;tag&quot;&gt;Microsoft&lt;/a&gt;&lt;/div&gt;  &lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script expr:src=&#39;&quot;http://feeds.feedburner.com/~s/SlingingSql?i=&quot; + data:post.url&#39; type=&quot;text/javascript&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;&lt;/div&gt;</description><link>http://sqlslinger.blogspot.com/2008/07/hierarchy-made-easier.html</link><author>noreply@blogger.com (Dan Ward)</author><thr:total>5</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6367058912647240061.post-8446230070208021431</guid><pubDate>Thu, 10 Jul 2008 23:59:00 +0000</pubDate><atom:updated>2008-07-10T21:08:25.952-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Encryption</category><category domain="http://www.blogger.com/atom/ns#">Security</category><category domain="http://www.blogger.com/atom/ns#">SQL Server 2008</category><title>Encryption and Key Management</title><description>&lt;p&gt;Wow, I&#39;m getting to post two days in a row again. I&#39;m finally getting into the right frame of mind I think.   &lt;br /&gt;Today I&#39;d like to look at a couple of new features that SQL Server 2008 introduces. Transparent Data Encryption (TDE) and Extensible Key Management (EKM). These subjects are closely related as we will see further on.    &lt;br /&gt;Transparent Data Encryption gives us the ability to encrypt our database objects without the need for changes to the client-side application. In other words, there is no need for us to provide decryption in our database applications. When enabled, data is encrypted prior to being written to the data file. This means that the data in the data file is encrypted, not just the access to it. With all the security concerns around identity theft and lost information, companies now have one less worry. Let&#39;s say that a company is running an application entirely on a laptop and storing the data in a local instance of SQL Server 2008. Yeah, I know, why would anyone do that, but for arguments sake, let&#39;s say they did. Now if the the laptop is stolen, and the data is not encrypted, the thief could very easily break into the data files, even without the SQL Server login info. But, if that data is encrypted with TDE, then that problem no longer exists. The data file can&#39;t be broken simply by attaching it to a new SQL Server. In fact TDE also encrypts backups so that the backup files are also useless to a thief. No more restoring the backup on another server.    &lt;br /&gt;TDE encryption is accomplished at the page level. The data is encrypted when it is written to disk and automatically decrypted when it is read from disk. The encryption will be based on a key of course, a database encryption key (DEK) that is protected with a certificate stored in the master database of the server.    &lt;br /&gt;As you may know, SQL Server 2005 offered column encryption, but this had its drawbacks. TDE is fully searchable. Column encryption is still part of SQL Server 2008, as it adds a finer control over what is encrypted. If only a few columns in a database need to be encrypted, such as SSN&#39;s, salary info, privacy data, then column encryption may be a better choice. TDE encrypts &lt;strong&gt;all&lt;/strong&gt; files of a database, including backups. If you use TDE for a database that is being mirrored, then the mirroring database will have the same encryption. One thing to note is that if any of the databases on a server use TDE, the tempdb database also gets encrypted and can harm performance.    &lt;br /&gt;Let&#39;s look at enabling TDE for a database.    &lt;br /&gt;&lt;/p&gt;  &lt;div&gt;   &lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;USE&lt;/span&gt; master;
&lt;span style=&quot;color: #0000ff&quot;&gt;GO&lt;/span&gt;

&lt;font color=&quot;#008000&quot;&gt;--We need a master key for our database&lt;/font&gt;
&lt;span style=&quot;color: #0000ff&quot;&gt;CREATE&lt;/span&gt;&lt;font color=&quot;#0000ff&quot;&gt; MASTER &lt;span style=&quot;color: #0000ff&quot;&gt;KEY&lt;/span&gt; ENCRYPTION&lt;/font&gt;
&lt;span style=&quot;color: #0000ff&quot;&gt;BY&lt;/span&gt; PASSWORD=&lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;p@ssw0rd&#39;&lt;/font&gt;&lt;/span&gt;;
&lt;span style=&quot;color: #0000ff&quot;&gt;GO&lt;/span&gt;

&lt;font color=&quot;#008000&quot;&gt;--Now we need a certificate to protect our key (DEK)&lt;/font&gt;
&lt;span style=&quot;color: #0000ff&quot;&gt;CREATE&lt;/span&gt; &lt;font color=&quot;#0000ff&quot;&gt;CERTIFICATE&lt;/font&gt; encryptCert
&lt;span style=&quot;color: #0000ff&quot;&gt;WITH&lt;/span&gt; &lt;font color=&quot;#0000ff&quot;&gt;SUBJECT&lt;/font&gt;=&lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;Certificate to protect DEK&#39;&lt;/font&gt;&lt;/span&gt;;
&lt;span style=&quot;color: #0000ff&quot;&gt;GO&lt;/span&gt;

&lt;font color=&quot;#008000&quot;&gt;--Now we change databases (certs and keys are created in the master db)&lt;/font&gt;
&lt;span style=&quot;color: #0000ff&quot;&gt;USE&lt;/span&gt; AdventureWorks;
&lt;span style=&quot;color: #0000ff&quot;&gt;GO&lt;/span&gt;

&lt;font color=&quot;#008000&quot;&gt;--Let&#39;s create our Database Encryption Key (DEK)&lt;/font&gt;
&lt;span style=&quot;color: #0000ff&quot;&gt;CREATE&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;DATABASE&lt;/span&gt; &lt;font color=&quot;#0000ff&quot;&gt;ENCRYPTION&lt;/font&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;KEY&lt;/span&gt;
&lt;span style=&quot;color: #0000ff&quot;&gt;WITH&lt;/span&gt; &lt;font color=&quot;#0000ff&quot;&gt;ALGORITHM=AES_128&lt;/font&gt;
&lt;font color=&quot;#0000ff&quot;&gt;ENCRYPTION &lt;span style=&quot;color: #0000ff&quot;&gt;BY&lt;/span&gt; SERVER CERTIFICATE&lt;/font&gt; encryptCert;
&lt;span style=&quot;color: #0000ff&quot;&gt;GO&lt;/span&gt;

&lt;font color=&quot;#008000&quot;&gt;--Now all we have to do is enable TDE&lt;/font&gt;
&lt;span style=&quot;color: #0000ff&quot;&gt;ALTER&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;DATABASE&lt;/span&gt; AdventureWorks
&lt;span style=&quot;color: #0000ff&quot;&gt;SET&lt;/span&gt; &lt;font color=&quot;#0000ff&quot;&gt;ENCRYPTION&lt;/font&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;ON&lt;/span&gt;;
&lt;font color=&quot;#0000ff&quot;&gt;GO&lt;/font&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Now, we can protect our DEK in a different way if we choose. We can use the Extensible Key Management (EKM) feature instead. This method will allow us to use an asymmetric key stored on a Hardware Security Module (HSM).It is a good idea, a best practice in fact, to store the keys used in encryption separately from the encrypted data. EKM allows us to follow this. EKM exposes encryption functionality to the vendors who make HSM devices. You can store encryption keys on devices such as USB devices and smartcards. HSM provides: Authentication with an EKM device, Separation of duties by additional authorization checks, Better performance for encrypt/decrypt operations, External generation of keys, storage, retrieval, distribution and disposal of keys, Key rotation.
  &lt;br /&gt;Since EKM is disabled by default, here is how we enable it:&lt;/p&gt;

&lt;div&gt;
  &lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;USE&lt;/span&gt; master;
&lt;span style=&quot;color: #0000ff&quot;&gt;GO&lt;/span&gt;

&lt;font color=&quot;#008000&quot;&gt;--Enabling &lt;span style=&quot;color: #0000ff&quot;&gt;is&lt;/span&gt; an advanced option&lt;/font&gt;
&lt;font color=&quot;#008000&quot;&gt;--so let&lt;/font&gt;&lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#008000&quot;&gt;&#39;s configure advanced options to show up&lt;/font&gt;
&lt;font color=&quot;#0000ff&quot;&gt;EXECUTE sp_configure&lt;/font&gt; &lt;font color=&quot;#ff0000&quot;&gt;&#39;&lt;/font&gt;&lt;/span&gt;&lt;font color=&quot;#ff0000&quot;&gt;show advanced option&#39;&lt;/font&gt;&lt;span style=&quot;color: #006080&quot;&gt;, &lt;font color=&quot;#ff0000&quot;&gt;&#39;&lt;/font&gt;&lt;/span&gt;&lt;font color=&quot;#ff0000&quot;&gt;1&lt;/font&gt;&lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;&lt;/font&gt;;
&lt;font color=&quot;#0000ff&quot;&gt;RECONFIGURE;&lt;/font&gt;
&lt;font color=&quot;#0000ff&quot;&gt;EXECUTE sp_configure&lt;/font&gt; &lt;font color=&quot;#ff0000&quot;&gt;&#39;&lt;/font&gt;&lt;/span&gt;&lt;font color=&quot;#ff0000&quot;&gt;EKM provider enabled&lt;/font&gt;&lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;&lt;/font&gt;, &lt;font color=&quot;#ff0000&quot;&gt;&#39;&lt;/font&gt;&lt;/span&gt;&lt;font color=&quot;#ff0000&quot;&gt;1&#39;&lt;/font&gt;;
&lt;span style=&quot;color: #0000ff&quot;&gt;RECONFIGURE&lt;/span&gt;;

&lt;font color=&quot;#008000&quot;&gt;--Here is how to protect an EKM module&lt;br /&gt;&lt;/font&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;CREATE&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;DATABASE&lt;/span&gt; &lt;font color=&quot;#0000ff&quot;&gt;ENCRYPTION &lt;span style=&quot;color: #0000ff&quot;&gt;KEY&lt;/span&gt;&lt;/font&gt; 
&lt;span style=&quot;color: #0000ff&quot;&gt;WITH&lt;/span&gt; &lt;font color=&quot;#0000ff&quot;&gt;ALGORITHM=AES_256&lt;/font&gt;
&lt;font color=&quot;#0000ff&quot;&gt;ENCRYPTION&lt;/font&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;BY&lt;/span&gt; EKM_SomeModuleDEK;
&lt;font color=&quot;#0000ff&quot;&gt;GO&lt;/font&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;And that&#39;s all there is to it. For now. One thing to note is that TDE and EKM are both based on the Microsoft Cryptographic API (MSCAPI) provider for encryption and key generation. For more information see the SQL Server 2008 BOL and MSDN.&lt;/p&gt;
&lt;div&gt;&lt;/div&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script expr:src=&#39;&quot;http://feeds.feedburner.com/~s/SlingingSql?i=&quot; + data:post.url&#39; type=&quot;text/javascript&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;&lt;/div&gt;</description><link>http://sqlslinger.blogspot.com/2008/07/encryption-and-key-management.html</link><author>noreply@blogger.com (Dan Ward)</author><thr:total>3</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6367058912647240061.post-9040419960364727342</guid><pubDate>Wed, 09 Jul 2008 15:34:00 +0000</pubDate><atom:updated>2008-07-11T10:15:57.480-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">SQL Server 2008</category><category domain="http://www.blogger.com/atom/ns#">T-SQL</category><title>Table-valued Parameters</title><description>&lt;p&gt;Last post I said I was going to try to get better at posting daily. I must apologize, as I realize it has been over a month, despite the best of intentions. Things are going well and work is getting busy, life is getting busier as well. My wife and I are dealing with our first teenager. I&#39;m sure there are those of you who can sympathize, and those that can&#39;t yet, run, while you can. Luckily for me, our oldest son is a good kid, so things could be much, much worse.&lt;/p&gt;  &lt;p&gt;Thanks to a gentleman I spoke with yesterday. I was interviewing him for a position at Sogeti, and he actually saw my blog link in my email signature and took the time to peek at it. His interest and feed back have once again prodded me into action. If you read my articles and like them but find I&#39;m not keeping pace with a daily blog, please feel free to drop me an email at &lt;a href=&quot;mailto:sql.slinger@gmail.com&quot;&gt;sql.slinger@gmail.com&lt;/a&gt;. I&#39;m always open to suggestions for topics too. &lt;/p&gt;  &lt;p&gt;Well, enough said about that, let&#39;s get to today&#39;s post. &lt;/p&gt;  &lt;p&gt;SQL Server 2005 gave us Table data types for use as variables and return values from functions. One missing piece was the ability to pass table data into a function or stored procedure as a parameter. This is now rectified in SQL Server 2008.&lt;/p&gt;  &lt;p&gt;Table-valued parameters offer flexibility, better performance than other methods of passing a list of parameters, and reduce server round trips. They can be used in place of BULK INSERT operations and are backed up by temporary tables, which are stored in the tempdb.&lt;/p&gt;  &lt;p&gt;ADO.NET, OLEDB and ODBC. as well as other client data access libraries, now include support for table-valued parameters&lt;/p&gt;  &lt;p&gt;A new data type was introduced to support table-valued parameters; the user-defined table type. Not to be confused with the table data type introduced in SQL Server 2005. The user-defined table type defines the structure of the table and allows constraints, such as PRIMARY KEY, UNIQUE, and CHECK to be defined on the table type. DEFAULT constraints are not support, nor are direct index creation.&lt;/p&gt;  &lt;p&gt;Let&#39;s look at it in action:&lt;/p&gt;  &lt;div&gt;   &lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;USE&lt;/span&gt; master;
&lt;span style=&quot;color: #0000ff&quot;&gt;&lt;font color=&quot;#000000&quot;&gt;GO&lt;/font&gt;&lt;/span&gt;
&lt;span style=&quot;color: #0000ff&quot;&gt;IF&lt;/span&gt; &lt;font color=&quot;#c0c0c0&quot;&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;NOT&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;EXISTS&lt;/span&gt;&lt;/font&gt;(&lt;span style=&quot;color: #0000ff&quot;&gt;SELECT&lt;/span&gt; name &lt;span style=&quot;color: #0000ff&quot;&gt;FROM&lt;/span&gt; &lt;font color=&quot;#008000&quot;&gt;sys.databases&lt;/font&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;WHERE&lt;/span&gt; name=N&lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;DBExample&#39;&lt;/font&gt;&lt;/span&gt;)
    &lt;span style=&quot;color: #0000ff&quot;&gt;CREATE&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;DATABASE&lt;/span&gt; DBExample;
&lt;span style=&quot;color: #0000ff&quot;&gt;&lt;font color=&quot;#000000&quot;&gt;GO&lt;/font&gt;&lt;/span&gt;
&lt;span style=&quot;color: #0000ff&quot;&gt;USE&lt;/span&gt; DBExample;
&lt;font color=&quot;#000000&quot;&gt;GO

--&lt;/font&gt;&lt;font color=&quot;#008000&quot;&gt;Working table definition&lt;/font&gt;
&lt;span style=&quot;color: #0000ff&quot;&gt;CREATE&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;TABLE&lt;/span&gt; RequestedTopics(TopicID &lt;span style=&quot;color: #0000ff&quot;&gt;INT&lt;/span&gt;, TopicSubject &lt;span style=&quot;color: #0000ff&quot;&gt;VARCHAR&lt;/span&gt;(128));

--&lt;font color=&quot;#008000&quot;&gt;Here is where we create the USER-DEFINED TYPE&lt;/font&gt;
&lt;span style=&quot;color: #0000ff&quot;&gt;CREATE&lt;/span&gt; TYPE BlogTopicType &lt;span style=&quot;color: #0000ff&quot;&gt;AS&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;TABLE&lt;/span&gt;(TopicID &lt;span style=&quot;color: #0000ff&quot;&gt;INT&lt;/span&gt;, TopicSubject &lt;span style=&quot;color: #0000ff&quot;&gt;VARCHAR&lt;/span&gt;(128));
&lt;span style=&quot;color: #0000ff&quot;&gt;&lt;font color=&quot;#000000&quot;&gt;GO&lt;/font&gt;&lt;/span&gt;

--&lt;font color=&quot;#008000&quot;&gt;We need a stored procedure to take the parameter&lt;/font&gt;
&lt;span style=&quot;color: #0000ff&quot;&gt;CREATE&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;PROCEDURE&lt;/span&gt; usp_InsertBlogTopic(
    @TopicTable BlogTopicType &lt;font color=&quot;#0000ff&quot;&gt;READONLY&lt;/font&gt;
)
&lt;span style=&quot;color: #0000ff&quot;&gt;AS&lt;/span&gt;
&lt;span style=&quot;color: #0000ff&quot;&gt;BEGIN&lt;/span&gt;
    &lt;span style=&quot;color: #0000ff&quot;&gt;SET&lt;/span&gt; &lt;font color=&quot;#0000ff&quot;&gt;NOCOUNT&lt;/font&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;ON&lt;/span&gt;;
    &lt;font color=&quot;#0000ff&quot;&gt;INSERT&lt;/font&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;INTO&lt;/span&gt; RequestedTopics(TopicID, TopicSubject)
    &lt;span style=&quot;color: #0000ff&quot;&gt;SELECT&lt;/span&gt; TopicID, TopicSubject &lt;span style=&quot;color: #0000ff&quot;&gt;FROM&lt;/span&gt; @TopicTable;
&lt;span style=&quot;color: #0000ff&quot;&gt;END&lt;/span&gt;
&lt;span style=&quot;color: #0000ff&quot;&gt;&lt;font color=&quot;#000000&quot;&gt;GO&lt;/font&gt;&lt;/span&gt;

&lt;font color=&quot;#008000&quot;&gt;--Now let&#39;&lt;/font&gt;&lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#008000&quot;&gt;s reference the table type we created&lt;/font&gt;
&lt;font color=&quot;#0000ff&quot;&gt;DECLARE&lt;/font&gt; &lt;font color=&quot;#000000&quot;&gt;@BTT &lt;font color=&quot;#0000ff&quot;&gt;AS&lt;/font&gt; BlogTopicType;&lt;/font&gt;

&lt;font color=&quot;#008000&quot;&gt;--Populate it with data&lt;/font&gt;
&lt;font color=&quot;#0000ff&quot;&gt;INSERT INTO&lt;/font&gt; &lt;font color=&quot;#000000&quot;&gt;@BTT(TopicID, TopicSubject)&lt;/font&gt; &lt;font color=&quot;#000000&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;VALUES&lt;/font&gt;(1,&lt;/font&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;&lt;/font&gt;&lt;/span&gt;&lt;font color=&quot;#ff0000&quot;&gt;Transparent Encryption&lt;/font&gt;&lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#000000&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;&lt;/font&gt;);&lt;/font&gt;
&lt;font color=&quot;#0000ff&quot;&gt;INSERT INTO&lt;/font&gt; &lt;font color=&quot;#000000&quot;&gt;@BTT(TopicID, TopicSubject)&lt;/font&gt; &lt;font color=&quot;#0000ff&quot;&gt;VALUES&lt;/font&gt;&lt;font color=&quot;#000000&quot;&gt;(2,&lt;/font&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;&lt;/font&gt;&lt;/span&gt;&lt;font color=&quot;#ff0000&quot;&gt;Service Broker Enhancements&lt;/font&gt;&lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#000000&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;&lt;/font&gt;);&lt;/font&gt;
&lt;font color=&quot;#008000&quot;&gt;--Now we may as well use something we learned before&lt;/font&gt;
&lt;font color=&quot;#0000ff&quot;&gt;INSERT INTO&lt;/font&gt; &lt;font color=&quot;#000000&quot;&gt;@BTT(TopicID, TopicSubject)&lt;/font&gt; 
    &lt;font color=&quot;#0000ff&quot;&gt;VALUES&lt;/font&gt;&lt;font color=&quot;#000000&quot;&gt;(3,&lt;/font&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;&lt;/font&gt;&lt;/span&gt;&lt;font color=&quot;#ff0000&quot;&gt;Analysis Services&lt;/font&gt;&lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;&lt;/font&gt;&lt;font color=&quot;#000000&quot;&gt;),(4,&lt;/font&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;&lt;/font&gt;&lt;/span&gt;&lt;font color=&quot;#ff0000&quot;&gt;Reporting Services&lt;/font&gt;&lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;&lt;/font&gt;&lt;font color=&quot;#000000&quot;&gt;),(5,&lt;font color=&quot;#ff0000&quot;&gt;&#39;&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font color=&quot;#ff0000&quot;&gt;Integration Services&lt;/font&gt;&lt;span style=&quot;color: #006080&quot;&gt;&lt;font color=&quot;#000000&quot;&gt;&lt;font color=&quot;#ff0000&quot;&gt;&#39;&lt;/font&gt;);&lt;/font&gt;

&lt;font color=&quot;#008000&quot;&gt;--Run the stored proc with the table-valued parameter&lt;/font&gt;
&lt;font color=&quot;#0000ff&quot;&gt;EXECUTE&lt;/font&gt; &lt;font color=&quot;#000000&quot;&gt;usp_InsertBlogTopic @BTT;&lt;/font&gt;

&lt;font color=&quot;#008000&quot;&gt;--Now let&#39;&lt;/font&gt;&lt;/span&gt;&lt;font color=&quot;#008000&quot;&gt;s see what&#39;s in our work table&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;SELECT&lt;/span&gt; * &lt;span style=&quot;color: #0000ff&quot;&gt;FROM&lt;/span&gt; RequestedTopics;&lt;/p&gt;&lt;p&gt;
&lt;font color=&quot;#000000&quot;&gt;Output:
-----&lt;/font&gt;&lt;span style=&quot;color: #008000&quot;&gt;-- ---------------&lt;/span&gt;
TopicID TopicSubject
1        Transparent Encryption
2        Service Broker Enhancements
3        Analysis Services
4        Reporting Services
5        Integration Services&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;/pre&gt;
&lt;/div&gt;  &lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script expr:src=&#39;&quot;http://feeds.feedburner.com/~s/SlingingSql?i=&quot; + data:post.url&#39; type=&quot;text/javascript&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;&lt;/div&gt;</description><link>http://sqlslinger.blogspot.com/2008/07/table-valued-parameters.html</link><author>noreply@blogger.com (Dan Ward)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6367058912647240061.post-2831343190744605209</guid><pubDate>Wed, 04 Jun 2008 21:01:00 +0000</pubDate><atom:updated>2008-07-11T10:20:17.242-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Assignment</category><category domain="http://www.blogger.com/atom/ns#">Row Constructors</category><category domain="http://www.blogger.com/atom/ns#">SQL Server 2008</category><category domain="http://www.blogger.com/atom/ns#">T-SQL</category><title>What&amp;#39;s New in T-SQL - Pt. 2</title><description>&lt;p&gt;Well, like all good things, I have the best intentions of posting daily, and what happens? Life, work, the real world invades. Sorry to be so long adding and improving the blog here.&lt;/p&gt;  &lt;p&gt;Let&#39;s look at some of the other new features that are now part of T-SQL.&lt;/p&gt;  &lt;p&gt;SQL Server 2008 introduces the concept of &lt;strong&gt;row constructors&lt;/strong&gt;. This allows us to create a table or table data type variable and then populate it with multiple sets of data in the same statement.&lt;/p&gt;  &lt;div&gt;   &lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;DECLARE&lt;/span&gt; @Product &lt;span style=&quot;color: #0000ff&quot;&gt;TABLE&lt;/span&gt;
(
    ProductID &lt;span style=&quot;color: #0000ff&quot;&gt;INT&lt;/span&gt;,
    ProductName NVARCHAR(64),
    ProductType &lt;span style=&quot;color: #0000ff&quot;&gt;INT&lt;/span&gt;,
    ProductCategory &lt;span style=&quot;color: #0000ff&quot;&gt;INT&lt;/span&gt;
);

--&lt;span style=&quot;color: #0000ff&quot;&gt;Old&lt;/span&gt; way
INSERT &lt;span style=&quot;color: #0000ff&quot;&gt;INTO&lt;/span&gt; @Product (ProductID, ProductName, ProductType, ProductCategory)
&lt;span style=&quot;color: #0000ff&quot;&gt;VALUES&lt;/span&gt; (1,&lt;span style=&quot;color: #006080&quot;&gt;&#39;Widget1&#39;&lt;/span&gt;,1,1);
INSERT &lt;span style=&quot;color: #0000ff&quot;&gt;INTO&lt;/span&gt; @Product (ProductID, ProductName, ProductType, ProductCategory)
&lt;span style=&quot;color: #0000ff&quot;&gt;VALUES&lt;/span&gt; (2,&lt;span style=&quot;color: #006080&quot;&gt;&#39;Widget2&#39;&lt;/span&gt;,1,2);
INSERT &lt;span style=&quot;color: #0000ff&quot;&gt;INTO&lt;/span&gt; @Product (ProductID, ProductName, ProductType, ProductCategory)
&lt;span style=&quot;color: #0000ff&quot;&gt;VALUES&lt;/span&gt; (3,&lt;span style=&quot;color: #006080&quot;&gt;&#39;Widget3&#39;&lt;/span&gt;,2,3);

--&lt;span style=&quot;color: #0000ff&quot;&gt;New&lt;/span&gt; way
INSERT &lt;span style=&quot;color: #0000ff&quot;&gt;INTO&lt;/span&gt; @Product (ProductID, ProductName, ProductType, ProductCategory)
&lt;span style=&quot;color: #0000ff&quot;&gt;VALUES&lt;/span&gt; (4,&lt;span style=&quot;color: #006080&quot;&gt;&#39;Gadget1&#39;&lt;/span&gt;,3,1), (5,&lt;span style=&quot;color: #006080&quot;&gt;&#39;Gadget2&#39;&lt;/span&gt;,3,2), (6,&lt;span style=&quot;color: #006080&quot;&gt;&#39;Gadget3&#39;&lt;/span&gt;,4,1);&lt;/pre&gt;
  &lt;style type=&quot;text/css&quot;&gt;



.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, &quot;Courier New&quot;, courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;/div&gt;

&lt;p&gt;Notice the difference! We can insert multiple rows of data in a single insert statement now. You can also use row constructors as pseudo tables if you specify a table name and column names for the set of values in the VALUE clause, as below.&lt;/p&gt;

&lt;div&gt;
  &lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;SELECT&lt;/span&gt; * &lt;span style=&quot;color: #0000ff&quot;&gt;FROM&lt;/span&gt; (
&lt;span style=&quot;color: #0000ff&quot;&gt;VALUES&lt;/span&gt;(1,&lt;span style=&quot;color: #006080&quot;&gt;&#39;Widget1&#39;&lt;/span&gt;,1,1),(2,&lt;span style=&quot;color: #006080&quot;&gt;&#39;Widget2&#39;&lt;/span&gt;,1,2),(3,&lt;span style=&quot;color: #006080&quot;&gt;&#39;Widget3&#39;&lt;/span&gt;,2,3)
)
Product (ProductID, ProductName, ProductType, ProductCategory);


&lt;span style=&quot;color: #0000ff&quot;&gt;Output&lt;/span&gt;:
ProductID   ProductName ProductType ProductCategory
---------&lt;span style=&quot;color: #008000&quot;&gt;-- ----------- ----------- ---------------&lt;/span&gt;
1           Widget1     1           1
2           Widget2     1           2
3           Widget3     2           3

(3 &lt;span style=&quot;color: #0000ff&quot;&gt;row&lt;/span&gt;(s) affected)&lt;/pre&gt;
&lt;/div&gt;
&lt;style type=&quot;text/css&quot;&gt;



.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, &quot;Courier New&quot;, courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Another new feature introduced to T-SQL by SQL Server 2008 is &lt;strong&gt;Single Statement Variable Declaration and Assignment&lt;/strong&gt;. This feature allows to declare a variable and assign it&#39;s value in the same statement. Similar to other .Net languages.&lt;/p&gt;

&lt;div&gt;
  &lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;--assign &lt;span style=&quot;color: #0000ff&quot;&gt;when&lt;/span&gt; declared
&lt;span style=&quot;color: #0000ff&quot;&gt;DECLARE&lt;/span&gt; @myInt &lt;span style=&quot;color: #0000ff&quot;&gt;INT&lt;/span&gt;=1, @MyName NVARCHAR(64)=N&lt;span style=&quot;color: #006080&quot;&gt;&#39;Dan&#39;&lt;/span&gt;;

--assign &lt;span style=&quot;color: #0000ff&quot;&gt;from&lt;/span&gt; a query &lt;span style=&quot;color: #0000ff&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;value&lt;/span&gt;
&lt;span style=&quot;color: #0000ff&quot;&gt;DECLARE&lt;/span&gt; @myTable &lt;span style=&quot;color: #0000ff&quot;&gt;TABLE&lt;/span&gt;(
    ID &lt;span style=&quot;color: #0000ff&quot;&gt;INT&lt;/span&gt;,
    Name NVARCHAR(64)
);
INSERT &lt;span style=&quot;color: #0000ff&quot;&gt;INTO&lt;/span&gt; @myTable(ID, Name)&lt;span style=&quot;color: #0000ff&quot;&gt;VALUES&lt;/span&gt;(1, &lt;span style=&quot;color: #006080&quot;&gt;&#39;Dan&#39;&lt;/span&gt;),(2, &lt;span style=&quot;color: #006080&quot;&gt;&#39;Bob&#39;&lt;/span&gt;);
&lt;span style=&quot;color: #0000ff&quot;&gt;DECLARE&lt;/span&gt; @yourName NVARCHAR(64)=
    (&lt;span style=&quot;color: #0000ff&quot;&gt;SELECT&lt;/span&gt; Name &lt;span style=&quot;color: #0000ff&quot;&gt;FROM&lt;/span&gt; @myTable &lt;span style=&quot;color: #0000ff&quot;&gt;WHERE&lt;/span&gt; ID=2);&lt;/pre&gt;
&lt;/div&gt;
&lt;style type=&quot;text/css&quot;&gt;



.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, &quot;Courier New&quot;, courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;One thing to note is that the order of precedence is not enforced when the DECLARE statement is processing. Therefore you cannot use a variable value from the same line to assign to another variable.&lt;/p&gt;

&lt;p&gt;The last item for today&#39;s post will be &lt;strong&gt;Compound Assignment Operators&lt;/strong&gt;.&amp;#160; Just like C++ and C#, T-SQL now has the compound assignment operators.&lt;/p&gt;

&lt;p&gt;Here is a table describing the operators and what they do.&lt;/p&gt;

&lt;div&gt;
  &lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;OPERATOR                          DESCRIPTION 
+=                                Add and assign 
-=                                Subtract and assign 
*=                                Multiply and assign 
/=                                Divide and assign 
%=                                Modulo and assign 
&amp;amp;=                                Bitwise AND and assign 
|=                                Bitwise logical OR and assign 
^=                                Bitwise exclusive OR and assign&lt;/pre&gt;
&lt;/div&gt;

&lt;div&gt;Compound operators work on the value already assigned to the variable and then use the operator to apply the right-side value to the current variable value.&lt;/div&gt;

&lt;div&gt;
  &lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;--assign &lt;span style=&quot;color: #0000ff&quot;&gt;when&lt;/span&gt; declared
&lt;span style=&quot;color: #0000ff&quot;&gt;DECLARE&lt;/span&gt; @myInt &lt;span style=&quot;color: #0000ff&quot;&gt;INT&lt;/span&gt;=1, @MyName NVARCHAR(64)=N&lt;span style=&quot;color: #006080&quot;&gt;&#39;Dan&#39;&lt;/span&gt;;

--assign &lt;span style=&quot;color: #0000ff&quot;&gt;from&lt;/span&gt; a query &lt;span style=&quot;color: #0000ff&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;value&lt;/span&gt;
&lt;span style=&quot;color: #0000ff&quot;&gt;DECLARE&lt;/span&gt; @myTable &lt;span style=&quot;color: #0000ff&quot;&gt;TABLE&lt;/span&gt;(
    ID &lt;span style=&quot;color: #0000ff&quot;&gt;INT&lt;/span&gt;,
    Name NVARCHAR(64)
);
INSERT &lt;span style=&quot;color: #0000ff&quot;&gt;INTO&lt;/span&gt; @myTable(ID, Name)&lt;span style=&quot;color: #0000ff&quot;&gt;VALUES&lt;/span&gt;(1, &lt;span style=&quot;color: #006080&quot;&gt;&#39;Dan&#39;&lt;/span&gt;),(2, &lt;span style=&quot;color: #006080&quot;&gt;&#39;Bob&#39;&lt;/span&gt;);
&lt;span style=&quot;color: #0000ff&quot;&gt;DECLARE&lt;/span&gt; @yourName NVARCHAR(64)=
    (&lt;span style=&quot;color: #0000ff&quot;&gt;SELECT&lt;/span&gt; Name &lt;span style=&quot;color: #0000ff&quot;&gt;FROM&lt;/span&gt; @myTable &lt;span style=&quot;color: #0000ff&quot;&gt;WHERE&lt;/span&gt; ID=2);

Result1     Result2
---------&lt;span style=&quot;color: #008000&quot;&gt;-- -------&lt;/span&gt;
20          1

(1 &lt;span style=&quot;color: #0000ff&quot;&gt;row&lt;/span&gt;(s) affected)


--Bitwise example
&lt;span style=&quot;color: #0000ff&quot;&gt;DECLARE&lt;/span&gt; @x TINYINT=10,@y TINYINT=2;
&lt;span style=&quot;color: #0000ff&quot;&gt;SET&lt;/span&gt; @x^=@y;  --Exclusive &lt;span style=&quot;color: #0000ff&quot;&gt;OR&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;of&lt;/span&gt; @x &lt;span style=&quot;color: #0000ff&quot;&gt;by&lt;/span&gt; @y
&lt;span style=&quot;color: #0000ff&quot;&gt;SELECT&lt;/span&gt; @x &lt;span style=&quot;color: #0000ff&quot;&gt;AS&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;Result&lt;/span&gt;;

&lt;span style=&quot;color: #0000ff&quot;&gt;Result&lt;/span&gt;
----&lt;span style=&quot;color: #008000&quot;&gt;--&lt;/span&gt;
&lt;span style=&quot;color: #008000&quot;&gt;8&lt;/span&gt;

(1 &lt;span style=&quot;color: #0000ff&quot;&gt;row&lt;/span&gt;(s) affected)&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;style type=&quot;text/css&quot;&gt;



.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, &quot;Courier New&quot;, courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;Well, that will rap things up for today. I will endeavor to do better at posting daily. Feel free to leave your comments, whether they are suggestions, requests, or just feedback, they are always welcome.&lt;/p&gt;  &lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script expr:src=&#39;&quot;http://feeds.feedburner.com/~s/SlingingSql?i=&quot; + data:post.url&#39; type=&quot;text/javascript&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;&lt;/div&gt;</description><link>http://sqlslinger.blogspot.com/2008/06/what-new-in-t-sql-pt-2.html</link><author>noreply@blogger.com (Dan Ward)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6367058912647240061.post-1560691704097762782</guid><pubDate>Wed, 28 May 2008 04:25:00 +0000</pubDate><atom:updated>2008-07-11T10:18:25.707-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">MERGE</category><category domain="http://www.blogger.com/atom/ns#">SQL Server 2008</category><category domain="http://www.blogger.com/atom/ns#">T-SQL</category><title>What’s New in T-SQL - Pt. 1</title><description>&lt;p&gt;Continuing, or should I say, beginning, our look at SQL Server 2008, I will be spending the next few posts discussing new and improved features in T-SQL.    &lt;br /&gt;Let&amp;#8217;s start by examining the MERGE statement.     &lt;br /&gt;What does the MERGE statement let you do? The MERGE statement will allow you to Insert, Update, and Delete rows in your target table in just a single statement. Before the MERGE statement you would have to do each operation separately using complex join statements or WHERE clauses.&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/p&gt;  &lt;h4&gt;Syntax: &lt;/h4&gt;  &lt;p&gt;(from SQL 2008 Books Online)&lt;/p&gt;  &lt;div style=&quot;border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4&quot;&gt;   &lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;[ &lt;span style=&quot;color: #0000ff&quot;&gt;WITH&lt;/span&gt; &amp;lt;common_table_expression&amp;gt; [,...n] ]
MERGE 
[ &lt;span style=&quot;color: #0000ff&quot;&gt;TOP&lt;/span&gt; ( expression ) [ &lt;span style=&quot;color: #0000ff&quot;&gt;PERCENT&lt;/span&gt; ] ] 
[ &lt;span style=&quot;color: #0000ff&quot;&gt;INTO&lt;/span&gt; ] target_table [ [ &lt;span style=&quot;color: #0000ff&quot;&gt;AS&lt;/span&gt; ] table_alias ]
        [ &lt;span style=&quot;color: #0000ff&quot;&gt;WITH&lt;/span&gt; ( &amp;lt;merge_hint&amp;gt; ) ]
&lt;span style=&quot;color: #0000ff&quot;&gt;USING&lt;/span&gt; &amp;lt;table_source&amp;gt;
&lt;span style=&quot;color: #0000ff&quot;&gt;ON&lt;/span&gt; &amp;lt;search_condition&amp;gt;
[ &lt;span style=&quot;color: #0000ff&quot;&gt;WHEN&lt;/span&gt; MATCHED [ &lt;span style=&quot;color: #0000ff&quot;&gt;AND&lt;/span&gt; &amp;lt;search_condition&amp;gt; ]
        &lt;span style=&quot;color: #0000ff&quot;&gt;THEN&lt;/span&gt; &amp;lt;merge_matched&amp;gt; ]
[ &lt;span style=&quot;color: #0000ff&quot;&gt;WHEN&lt;/span&gt; [TARGET] &lt;span style=&quot;color: #0000ff&quot;&gt;NOT&lt;/span&gt; MATCHED [ &lt;span style=&quot;color: #0000ff&quot;&gt;AND&lt;/span&gt; &amp;lt;search_condition&amp;gt; ]
        &lt;span style=&quot;color: #0000ff&quot;&gt;THEN&lt;/span&gt; &amp;lt;merge_not_matched&amp;gt; ]
[ &lt;span style=&quot;color: #0000ff&quot;&gt;WHEN&lt;/span&gt; SOURCE &lt;span style=&quot;color: #0000ff&quot;&gt;NOT&lt;/span&gt; MATCHED [ &lt;span style=&quot;color: #0000ff&quot;&gt;AND&lt;/span&gt; &amp;lt;search_condition&amp;gt; ]
        &lt;span style=&quot;color: #0000ff&quot;&gt;THEN&lt;/span&gt; &amp;lt;merge_ matched&amp;gt; ]
&amp;lt;output_clause&amp;gt;
[ &lt;span style=&quot;color: #0000ff&quot;&gt;OPTION&lt;/span&gt; ( &amp;lt;query_hint&amp;gt; [ ,...n ] ) ];

&amp;lt;merge_hint&amp;gt;::=
        { [ &amp;lt;table_hint_limited&amp;gt; [ ,...n ] ]
    [ [ , ] &lt;span style=&quot;color: #0000ff&quot;&gt;INDEX&lt;/span&gt; ( index_val [ ,...n ] ) ] }

&amp;lt;table_source&amp;gt; ::= 
{
        table_or_view_name [ [ &lt;span style=&quot;color: #0000ff&quot;&gt;AS&lt;/span&gt; ] table_alias ] [ &amp;lt;tablesample_clause&amp;gt; ] 
                [ &lt;span style=&quot;color: #0000ff&quot;&gt;WITH&lt;/span&gt; ( table_hint [ [ , ]...n ] ) ] 
    | rowset_function [ [ &lt;span style=&quot;color: #0000ff&quot;&gt;AS&lt;/span&gt; ] table_alias ] 
                [ ( bulk_column_alias [ ,...n ] ) ] 
    | user_defined_function [ [ &lt;span style=&quot;color: #0000ff&quot;&gt;AS&lt;/span&gt; ] table_alias ]
    | &lt;span style=&quot;color: #0000ff&quot;&gt;OPENXML&lt;/span&gt; &amp;lt;openxml_clause&amp;gt; 
    | derived_table [ &lt;span style=&quot;color: #0000ff&quot;&gt;AS&lt;/span&gt; ] table_alias [ ( column_alias [ ,...n ] ) ] 
    | &amp;lt;joined_table&amp;gt; 
    | &amp;lt;pivoted_table&amp;gt; 
    | &amp;lt;unpivoted_table&amp;gt; 
}

&amp;lt;merge_matched&amp;gt;::=
                { &lt;span style=&quot;color: #0000ff&quot;&gt;UPDATE&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;SET&lt;/span&gt; &amp;lt;set_clause&amp;gt; | &lt;span style=&quot;color: #0000ff&quot;&gt;DELETE&lt;/span&gt; }

&amp;lt;set_clause&amp;gt;::=
    { column_name = { expression | &lt;span style=&quot;color: #0000ff&quot;&gt;DEFAULT&lt;/span&gt; | &lt;span style=&quot;color: #0000ff&quot;&gt;NULL&lt;/span&gt; }
  | { udt_column_name. { { property_name = expression 
        | field_name = expression } 
        | method_name ( argument [ ,...n ] ) } }
  | column_name { .&lt;span style=&quot;color: #0000ff&quot;&gt;WRITE&lt;/span&gt; ( expression , @Offset , @Length ) }
  | @&lt;span style=&quot;color: #0000ff&quot;&gt;variable&lt;/span&gt; = expression 
    } [ ,...n ] 

&amp;lt;merge_not_matched&amp;gt;::=
        INSERT [ ( &amp;lt;column_list&amp;gt; ) ] 
                { &lt;span style=&quot;color: #0000ff&quot;&gt;VALUES&lt;/span&gt; ( &amp;lt;values_list&amp;gt; )
             | &lt;span style=&quot;color: #0000ff&quot;&gt;DEFAULT&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;VALUES&lt;/span&gt; }

&amp;lt;output_clause&amp;gt;::=
{
    [ &lt;span style=&quot;color: #0000ff&quot;&gt;OUTPUT&lt;/span&gt; &amp;lt;dml_select_list&amp;gt; &lt;span style=&quot;color: #0000ff&quot;&gt;INTO&lt;/span&gt; { @table_variable | output_table }
        [ (column_list) ] ]
        [ &lt;span style=&quot;color: #0000ff&quot;&gt;OUTPUT&lt;/span&gt; &amp;lt;dml_select_list&amp;gt; ]
}

&amp;lt;dml_select_list&amp;gt;::=
{ &amp;lt;column_name&amp;gt; | scalar_expression } [ [&lt;span style=&quot;color: #0000ff&quot;&gt;AS&lt;/span&gt;] column_alias_identifier ]
     [ ,...n ]

&amp;lt;column_name&amp;gt; ::=
    { DELETED | INSERTED | from_table_name } . { * | column_name }
   | $ACTION&lt;/pre&gt;
&lt;/div&gt;

&lt;h4&gt;Example:&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Scenario:&lt;/strong&gt; You regularly update a table from a bulk source. The incoming dataset has new records and updates to existing records. 

  &lt;br /&gt;You maintain a table of the current inventory, which is updated nightly to reflect the transactions from the day. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Assumptions:&lt;/strong&gt; Products are kept in a Product table which is not shown below. A foreign-key relationship exists with the Inventory table. The LastModified field is automatically populated by a default for all inserts.&lt;/p&gt;

&lt;div&gt;
  &lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;DECLARE&lt;/span&gt; @InventoryMaster &lt;span style=&quot;color: #0000ff&quot;&gt;TABLE&lt;/span&gt;(InventoryID &lt;span style=&quot;color: #0000ff&quot;&gt;INT&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;IDENTITY&lt;/span&gt;,
ProductID &lt;span style=&quot;color: #0000ff&quot;&gt;INT&lt;/span&gt;,
QtyOnHand &lt;span style=&quot;color: #0000ff&quot;&gt;INT&lt;/span&gt;,
ReorderLevel &lt;span style=&quot;color: #0000ff&quot;&gt;INT&lt;/span&gt;,
LastModified datetime &lt;span style=&quot;color: #0000ff&quot;&gt;DEFAULT&lt;/span&gt; GETDATE()
);

&lt;span style=&quot;color: #0000ff&quot;&gt;DECLARE&lt;/span&gt; @DailyTransactions &lt;span style=&quot;color: #0000ff&quot;&gt;TABLE&lt;/span&gt;(ProductID &lt;span style=&quot;color: #0000ff&quot;&gt;INT&lt;/span&gt;, TransQty &lt;span style=&quot;color: #0000ff&quot;&gt;INT&lt;/span&gt;);

INSERT &lt;span style=&quot;color: #0000ff&quot;&gt;INTO&lt;/span&gt; @InventoryMaster (ProductID, QtyOnHand, ReorderLevel) 
&lt;span style=&quot;color: #0000ff&quot;&gt;VALUES&lt;/span&gt; (1, 100, 20), (2, 50, 10), (3, 1000, 100), (25, 200, 50), (26, 200, 20);

INSERT &lt;span style=&quot;color: #0000ff&quot;&gt;INTO&lt;/span&gt; @DailyTransactions (ProductID, TransQty)
&lt;span style=&quot;color: #0000ff&quot;&gt;VALUES&lt;/span&gt; (1, -20), (1, 5), (3, -25), (3, 10), (25, -5), (24, 10), (25, 50);

&lt;span style=&quot;color: #0000ff&quot;&gt;SELECT&lt;/span&gt; * &lt;span style=&quot;color: #0000ff&quot;&gt;FROM&lt;/span&gt; @InventoryMaster;

MERGE @InventoryMaster inv
&lt;span style=&quot;color: #0000ff&quot;&gt;USING&lt;/span&gt; (&lt;span style=&quot;color: #0000ff&quot;&gt;SELECT&lt;/span&gt; ProductID, &lt;span style=&quot;color: #0000ff&quot;&gt;SUM&lt;/span&gt;(TransQty) &lt;span style=&quot;color: #0000ff&quot;&gt;as&lt;/span&gt; TransQty &lt;span style=&quot;color: #0000ff&quot;&gt;FROM&lt;/span&gt; @DailyTransactions &lt;span style=&quot;color: #0000ff&quot;&gt;GROUP&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;BY&lt;/span&gt; ProductID) dt
&lt;span style=&quot;color: #0000ff&quot;&gt;ON&lt;/span&gt; inv.ProductID = dt.ProductID
&lt;span style=&quot;color: #0000ff&quot;&gt;WHEN&lt;/span&gt; MATCHED
&lt;span style=&quot;color: #0000ff&quot;&gt;THEN&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;UPDATE&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;SET&lt;/span&gt; QtyOnHand += TransQty
&lt;span style=&quot;color: #0000ff&quot;&gt;WHEN&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;NOT&lt;/span&gt; MATCHED 
&lt;span style=&quot;color: #0000ff&quot;&gt;THEN&lt;/span&gt; INSERT &lt;span style=&quot;color: #0000ff&quot;&gt;VALUES&lt;/span&gt;(ProductID, TransQty, TransQty*.25,GetDate())
&lt;span style=&quot;color: #0000ff&quot;&gt;OUTPUT&lt;/span&gt; $&lt;span style=&quot;color: #0000ff&quot;&gt;action&lt;/span&gt;,inserted.*,deleted.*;

&lt;span style=&quot;color: #0000ff&quot;&gt;SELECT&lt;/span&gt; * &lt;span style=&quot;color: #0000ff&quot;&gt;FROM&lt;/span&gt; @InventoryMaster;&lt;/pre&gt;
&lt;/div&gt;

&lt;div&gt;&amp;#160;&lt;/div&gt;

&lt;div&gt;You will notice that the insert statements are a little different than you may be used to. The above example utilizes row constructors (new to SQL Server 2008). You will also keenly observe the use of &amp;quot;+=&amp;quot;, and realize that SQL Server 2008 must now allow compound assignment operators, and you would be right. We will cover both of these in tomorrows post.&lt;/div&gt;

&lt;div&gt;&amp;#160;&lt;/div&gt;

&lt;div&gt;For now, be aware that there are many ways to construct your MERGE statement. The example utilizes a sub-select query from the daily transaction table to sum the amount deltas together. If they aren&#39;t summed you will get an error because you are not allowed to perform multiple updates on a row within the same MERGE statement.&lt;/div&gt;  &lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script expr:src=&#39;&quot;http://feeds.feedburner.com/~s/SlingingSql?i=&quot; + data:post.url&#39; type=&quot;text/javascript&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;&lt;/div&gt;</description><link>http://sqlslinger.blogspot.com/2008/05/whats-new-in-t-sql-pt-1.html</link><author>noreply@blogger.com (Dan Ward)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6367058912647240061.post-2089646369413680383</guid><pubDate>Fri, 23 May 2008 21:14:00 +0000</pubDate><atom:updated>2008-07-11T10:17:31.847-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">SQL Server 2008</category><title>Katmai 1st Look</title><description>&lt;p&gt;&lt;span style=&quot;FONT-FAMILY: Calibri&quot;&gt;&lt;span style=&quot;FONT-SIZE: 130%&quot;&gt;A few weeks ago I presented at a Microsoft/&lt;/span&gt;&lt;a href=&quot;http://www.us.sogeti.com/&quot; target=&quot;_blank&quot; &gt;&lt;span style=&quot;FONT-SIZE: 130%&quot;&gt;Sogeti USA&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;FONT-SIZE: 130%&quot;&gt; joint event in Dayton. The topic was SQL Server 2008 - What&amp;rsquo;s New. I had just over an hour for my presentation, and it turned out this was just not nearly enough time to do justice to all the new and improved features found in Katmai. I have been looking for something to motivate me into starting a blog and now it looks like I have found something. In order to rectify the injustice done to the topic because of time constraints I will be publishing a series of posts on my blog. In each post we&amp;rsquo;ll explore a new feature or an improvement in depth. Join with me and participate with your comments. Together we will uncover the mysteries of SQL Server 2008.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;FONT-SIZE: 130%; FONT-FAMILY: Calibri&quot;&gt;Look for my next post to begin our journey with &amp;quot;What&amp;rsquo;s New in T-SQL&amp;quot;&lt;/span&gt;&lt;/p&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script expr:src=&#39;&quot;http://feeds.feedburner.com/~s/SlingingSql?i=&quot; + data:post.url&#39; type=&quot;text/javascript&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;&lt;/div&gt;</description><link>http://sqlslinger.blogspot.com/2008/05/katmai-1st-look.html</link><author>noreply@blogger.com (Dan Ward)</author><thr:total>0</thr:total></item></channel></rss>