<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-902486075140485537</atom:id><lastBuildDate>Fri, 08 Jul 2011 18:54:02 +0000</lastBuildDate><category>Integration Services</category><category>Management Studio 2008</category><category>tools</category><category>SQL Server 2008</category><category>cloud computing</category><category>things I like</category><category>refactoring</category><category>tsql</category><category>ALTER TABLE</category><category>CREATE TRIGGER</category><category>tips and tricks</category><category>programming</category><category>naming convention</category><category>SQL Server</category><category>SQL Server 2005</category><category>CREATE TABLE</category><category>audit</category><category>algorithms</category><category>AdventureWorks</category><category>SSMS</category><category>t-sql</category><category>DDL</category><category>constraints</category><category>welcome</category><category>data structures</category><category>CREATE VIEW</category><category>good practices</category><category>script</category><category>DROP TABLE</category><category>SQLServerPedia Syndication</category><category>code</category><category>SSIS</category><category>INSTEAD OF trigger</category><category>execution plan</category><title>Piotr Rodak: if datepart(dw, getdate()) in (6, 7) use pubs;</title><description>My blog about SQL Server, performance tuning, coding practices, tips and tricks.</description><link>http://usepubs.blogspot.com/</link><managingEditor>noreply@blogger.com (Piotr Rodak)</managingEditor><generator>Blogger</generator><openSearch:totalResults>12</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/PiotrRodak" /><feedburner:info uri="piotrrodak" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><guid isPermaLink="false">tag:blogger.com,1999:blog-902486075140485537.post-2269815484028743132</guid><pubDate>Sat, 21 Aug 2010 21:36:00 +0000</pubDate><atom:updated>2010-08-21T22:36:39.648+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">SQLServerPedia Syndication</category><title>Moving blog… again</title><description>&lt;p&gt;Hi&lt;/p&gt;  &lt;p&gt;It’s been a while since I have written here. The main reason is that it is summer and I was on vacations, and not very keen on sitting in front of the computer. &lt;/p&gt;  &lt;p&gt;The other reason is that I have decided to move the blog again. The visibility of this blog unfortunately is not great, even though I think I wrote a few posts which are pretty interesting – so say those who read them :). I made quite a bit of effort to increase the visibility of the blog with great help of &lt;a href="http://www.brentozar.com/"&gt;Brent Ozar&lt;/a&gt;. Unfortunately, the main problem is still practical absence of my posts in the Google search results. This makes my posts life very short and I feel they could do better.&lt;/p&gt;  &lt;p&gt;Thankfully &lt;a href="http://sqlblog.com/blogs/adam_machanic/default.aspx" target="_blank"&gt;Adam Machanic&lt;/a&gt; sent me email if I would consider setting up blog on the &lt;a href="http://sqlblog.com/"&gt;SQLBlog.com&lt;/a&gt;. I must say I found this very rewarding, because bloggers on SQLBlog.com belong to the finest experts of the SQL Server. I decided to move my blog to SQLBlog.com, I hope the content I will publish will serve more developers looking for knowledge. So please repoint your RSS readers to my new blog: &lt;a title="http://sqlblog.com/blogs/piotr_rodak" href="http://sqlblog.com/blogs/piotr_rodak"&gt;http://sqlblog.com/blogs/piotr_rodak&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;See you there!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/902486075140485537-2269815484028743132?l=usepubs.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=DocYO80kwoQ:qyhRcs0BatM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=DocYO80kwoQ:qyhRcs0BatM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=DocYO80kwoQ:qyhRcs0BatM:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=DocYO80kwoQ:qyhRcs0BatM:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=DocYO80kwoQ:qyhRcs0BatM:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=DocYO80kwoQ:qyhRcs0BatM:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=DocYO80kwoQ:qyhRcs0BatM:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=DocYO80kwoQ:qyhRcs0BatM:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=DocYO80kwoQ:qyhRcs0BatM:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=DocYO80kwoQ:qyhRcs0BatM:3QFJfmc7Om4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=DocYO80kwoQ:qyhRcs0BatM:3QFJfmc7Om4" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PiotrRodak/~4/DocYO80kwoQ" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PiotrRodak/~3/DocYO80kwoQ/moving-blog-again.html</link><author>noreply@blogger.com (Piotr Rodak)</author><thr:total>0</thr:total><feedburner:origLink>http://usepubs.blogspot.com/2010/08/moving-blog-again.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-902486075140485537.post-7877123044926750654</guid><pubDate>Thu, 22 Jul 2010 07:15:00 +0000</pubDate><atom:updated>2010-07-22T08:15:28.183+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">data structures</category><category domain="http://www.blogger.com/atom/ns#">algorithms</category><category domain="http://www.blogger.com/atom/ns#">SQLServerPedia Syndication</category><category domain="http://www.blogger.com/atom/ns#">programming</category><category domain="http://www.blogger.com/atom/ns#">cloud computing</category><category domain="http://www.blogger.com/atom/ns#">SQL Server</category><title>With head in the clouds</title><description>&lt;p&gt;I write this post inspired by excellent article of Jeremiah Peschka (&lt;a href="http://facility9.com/" target="_blank"&gt;blog&lt;/a&gt;) who wrote about the &lt;a href="http://facility9.com/2010/07/15/the-future-of-databases" target="_blank"&gt;future of databases&lt;/a&gt;. I think that this is a good topic to write something I hope meaningful about.&lt;/p&gt;  &lt;p&gt;Jeremiah made several good observations about the nature of current database designs and technologies and what it seems to be an upcoming technology of future – the name-value stores. &lt;/p&gt;  &lt;p&gt;I am sometimes faced with opinions of sort “Dude, these relational databases are sooo gone!”. Are they? Let’s see, what good “no sql”, cloud database should have:&lt;/p&gt;  &lt;p&gt;Obviously trendy key-value collection. This is implemented usually using &lt;a href="http://en.wikipedia.org/wiki/Hash_table" target="_blank"&gt;hash table&lt;/a&gt;, where key is transformed to certain numeric value, and this value is used to index table that holds actual data values. To add a value, you have to calculate hash of the key, resolve conflict and insert the value into appropriate index of the table. The other option is to use &lt;a href="http://en.wikipedia.org/wiki/Tree_%28data_structure%29" target="_blank"&gt;tree data structure&lt;/a&gt;, where nodes are balanced according to the key value, and each node contains actual data. To access data, you have to traverse tree based on the value of the key. When you insert a value, you have to rebalance tree (if you use &lt;a href="http://en.wikipedia.org/wiki/Balanced_tree" target="_blank"&gt;balanced tree&lt;/a&gt;) to maintain predictable access time to the data.&lt;/p&gt;  &lt;p&gt;In some cases you want to retrieve collection of objects within a specific order. This can be done in two ways – either you &lt;a href="http://en.wikipedia.org/wiki/Sort_algorithm" target="_blank"&gt;sort&lt;/a&gt; data each time the collection is requested, or you maintain doubly &lt;a href="http://en.wikipedia.org/wiki/Linked_list" target="_blank"&gt;linked list&lt;/a&gt; of keys that enables you to move between nodes in specific order. Ah these old good &lt;a href="http://www.daniweb.com/code/snippet216960.html" target="_blank"&gt;*prev and *next pointers&lt;/a&gt;. The first option gives you overhead each time you retrieve the data, but doesn’t necessarily significantly consume memory. The second option requires additional memory and management for adding or removing values. If you change key value, the list has to be updated so the elements are returned in proper order.&lt;/p&gt;  &lt;p&gt;Believe it or not, even clouds touch the ground sometimes. Even the cloud data have to be persisted sometimes. How do you do it? You can use either proprietary binary file structure for performance or xml, that’s pretty much it. When you write the data, you have to ensure that some other process is not writing it as well – concurrency control. You have to ensure that when data are written, other processes can read consistent view of data. There’s another thing – you don’t always write all data you have in memory. You should be able to persist only changes. To identify changed values on disk and update or insert or delete them accordingly. If you want to keep performance, these disk data structures have to be optimized for searching – here we have indexes.&lt;/p&gt;  &lt;p&gt;All these points above are key factors of a good “no sql” database. All these points are also implemented in SQL Server. You have balanced trees for indexes, hash tables for plan cache, key indexed tables for row offsets on page level, linked lists of pages in indexes, sorting, data persistence technology optimized for concurrency and speed. You can, if you want to access data through OR mapper so you deal with collections, attributes etc. &lt;/p&gt;  &lt;p&gt;So, what are the differences? The main and most important difference is the replication. SQL Server insists on storing changed data to disk first and then replicates it, the cloud data stores do the opposite – they replicate data to neighbouring nodes of the network before persisting it. This change of approach was made possible by development of technology, growing speeds of networks and capacities of memory installed on servers. It may be cheaper and faster to throw a few gigabytes over the fast network to the other side of the world than to store them in local SAN. The idea relies on the statistics – it is very unlikely that all of a sudden servers located in several places in the world will fail at the same time. SQL Server approach stems from old times, where servers were mostly standalone machines which had to ensure that no matter what, data will be available after disaster recovery.&lt;/p&gt;  &lt;p&gt;The cloud applications often use traditional databases as their back ends in various locations for the reasons I described above. Traditional databases offer transactional and safe way of persisting data, what has to happen at some point of time. &lt;/p&gt;  &lt;p&gt;I hope that this article will shed some light on internal implementation of cloud databases, especially the fact that all data structures and algorithms were invented may years ago, sometimes 50 years ago. It’s the power of technology and money what made cloud data stores possible, nothing else. There is nothing new under the sun.&lt;/p&gt;  &lt;div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:3dbb35f0-a337-4268-affd-f9a648eb6f41" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/cloud" rel="tag"&gt;cloud&lt;/a&gt;,&lt;a href="http://technorati.com/tags/cloud+computing" rel="tag"&gt;cloud computing&lt;/a&gt;,&lt;a href="http://technorati.com/tags/SQL+Server" rel="tag"&gt;SQL Server&lt;/a&gt;,&lt;a href="http://technorati.com/tags/algorrithms" rel="tag"&gt;algorrithms&lt;/a&gt;,&lt;a href="http://technorati.com/tags/data+structures" rel="tag"&gt;data structures&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/902486075140485537-7877123044926750654?l=usepubs.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=iooybyjVhmE:LdbgpOdSI_8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=iooybyjVhmE:LdbgpOdSI_8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=iooybyjVhmE:LdbgpOdSI_8:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=iooybyjVhmE:LdbgpOdSI_8:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=iooybyjVhmE:LdbgpOdSI_8:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=iooybyjVhmE:LdbgpOdSI_8:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=iooybyjVhmE:LdbgpOdSI_8:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=iooybyjVhmE:LdbgpOdSI_8:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=iooybyjVhmE:LdbgpOdSI_8:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=iooybyjVhmE:LdbgpOdSI_8:3QFJfmc7Om4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=iooybyjVhmE:LdbgpOdSI_8:3QFJfmc7Om4" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PiotrRodak/~4/iooybyjVhmE" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PiotrRodak/~3/iooybyjVhmE/with-head-in-clouds.html</link><author>noreply@blogger.com (Piotr Rodak)</author><thr:total>4</thr:total><feedburner:origLink>http://usepubs.blogspot.com/2010/07/with-head-in-clouds.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-902486075140485537.post-396899616345616774</guid><pubDate>Fri, 16 Jul 2010 20:38:00 +0000</pubDate><atom:updated>2010-07-16T21:52:45.495+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">SQL Server 2008</category><category domain="http://www.blogger.com/atom/ns#">tsql</category><category domain="http://www.blogger.com/atom/ns#">tips and tricks</category><category domain="http://www.blogger.com/atom/ns#">SQLServerPedia Syndication</category><category domain="http://www.blogger.com/atom/ns#">code</category><category domain="http://www.blogger.com/atom/ns#">programming</category><category domain="http://www.blogger.com/atom/ns#">CREATE TRIGGER</category><category domain="http://www.blogger.com/atom/ns#">SQL Server 2005</category><category domain="http://www.blogger.com/atom/ns#">good practices</category><category domain="http://www.blogger.com/atom/ns#">script</category><category domain="http://www.blogger.com/atom/ns#">audit</category><title>Disabling audit triggers</title><description>&lt;p&gt;This is a follow up to the posts about audit triggers. I wrote about them some time ago, on my previous blogging platform. The &lt;a href="http://sqlblogcasts.com/blogs/piotr_rodak/archive/2010/04/28/columns-updated.aspx" target="_blank"&gt;first post&lt;/a&gt; discussed COLUMS_UPDATED() function that is very useful in triggers if you want to find out which columns are affected by DML operation. &lt;a href="http://sqlblogcasts.com/blogs/piotr_rodak/archive/2010/05/11/the-penultimate-audit-trigger.aspx" target="_blank"&gt;Second post&lt;/a&gt; showed how you can create an audit framework that subsequently is used to log what happens to data when users modify it.&lt;/p&gt;
&lt;p&gt;Now, there are situations, when you want to make changes to a table, but you don’t want to have these operations logged. And I am not talking about criminal activities – but for example, a table is populated daily by ETL process which updates or inserts thousands of rows. Sometimes it doesn’t make sense to log all these operations – after all triggers incur some performance degradation on the database.&lt;/p&gt;
&lt;p&gt;There are several ways to disable a trigger. First, you can use &lt;a href="http://msdn.microsoft.com/en-us/library/ms189748.aspx" target="_blank"&gt;disable trigger&lt;/a&gt; statement This approach has one drawback – when you disable trigger, it is disabled for every user who modifies the data. So you may loose audit entries while your ETL is running. In some scenarios it’s not an option.&lt;/p&gt;
&lt;p&gt;Alternatively you can implement trigger to check for certain condition and decide whether DML operation should be audited or not. There are several ways of doing this. Two are described by Itzik Ben-Gan in his excellent &lt;a href="http://www.amazon.com/Inside-Microsoft-Server-2005-Pro-Developer/dp/0735621977" target="_blank"&gt;Inside SQL Server 2005 - T-SQL Programming&lt;/a&gt;. Triggers can check if a table with specific name exists in the temp database or use &lt;a href="http://msdn.microsoft.com/en-us/library/aa214382%28SQL.80%29.aspx" target="_blank"&gt;session context&lt;/a&gt;. The disadvantage of these options is that you have to modify code external to triggers, for example your stored procedures or batches.&lt;/p&gt;
&lt;p&gt;You can check if there is certain entry in a configuration table. For example you can have table Audit.tIgnoreUsers which will contain user names for which you don't want to audit. Then, there’s a simple query to decide if the trigger should proceed or not:&lt;/p&gt;
&lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; direction: ltr; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; height: 56px; background-color: #f4f4f4; text-align: left"&gt;&lt;div id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum1" style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;exists&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;select&lt;/span&gt; 1 &lt;span style="color: #0000ff"&gt;from&lt;/span&gt; Audit.tIgnoreUsers &lt;span style="color: #0000ff"&gt;where&lt;/span&gt; UserName = suser_name()))&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; height: 14px; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum2" style="color: #606060"&gt;   2:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;return&lt;/span&gt;;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Alternatively, you can check if particular user belongs to particular role. To do this, you have to create role first and add user that you want to exclude from auditing.&lt;/p&gt;
&lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; direction: ltr; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4; text-align: left"&gt;&lt;div id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum1" style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; &lt;span style="color: #0000ff"&gt;not&lt;/span&gt; &lt;span style="color: #0000ff"&gt;exists&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;select&lt;/span&gt; 1 &lt;span style="color: #0000ff"&gt;from&lt;/span&gt; sys.database_principals &lt;span style="color: #0000ff"&gt;where&lt;/span&gt; name = &lt;span style="color: #006080"&gt;'ExcludeFromAudit'&lt;/span&gt; &lt;span style="color: #0000ff"&gt;and&lt;/span&gt; type=&lt;span style="color: #006080"&gt;'R'&lt;/span&gt;)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum2" style="color: #606060"&gt;   2:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;exec&lt;/span&gt; sp_executesql N&lt;span style="color: #006080"&gt;'create role ExcludeFromAudit authorization dbo'&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum3" style="color: #606060"&gt;   3:&lt;/span&gt;&amp;#160; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum4" style="color: #606060"&gt;   4:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;go&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum5" style="color: #606060"&gt;   5:&lt;/span&gt;&amp;#160; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum6" style="color: #606060"&gt;   6:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;exec&lt;/span&gt; sp_addrolemember &lt;span style="color: #006080"&gt;'ExcludeFromAudit'&lt;/span&gt;, &lt;span style="color: #006080"&gt;'ETLLogin'&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum7" style="color: #606060"&gt;   7:&lt;/span&gt;&amp;#160; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum8" style="color: #606060"&gt;   8:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;go&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum9" style="color: #606060"&gt;   9:&lt;/span&gt;&amp;#160; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum10" style="color: #606060"&gt;  10:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;raiserror&lt;/span&gt;(&lt;span style="color: #006080"&gt;'Logins skipped in auditing: '&lt;/span&gt;, 10, 1) &lt;span style="color: #0000ff"&gt;with&lt;/span&gt; nowait;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum11" style="color: #606060"&gt;  11:&lt;/span&gt;&amp;#160; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum12" style="color: #606060"&gt;  12:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;exec&lt;/span&gt; sp_helprolemember &lt;span style="color: #006080"&gt;'ExcludeFromAudit'&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Then, in the audit trigger you just add code somewhere on the top of the trigger:&lt;/p&gt;
&lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; direction: ltr; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4; text-align: left"&gt;&lt;div id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum1" style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(is_rolemember(&lt;span style="color: #006080"&gt;'ExcludeFromAudit'&lt;/span&gt;) = 1)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum2" style="color: #606060"&gt;   2:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;begin&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum3" style="color: #606060"&gt;   3:&lt;/span&gt;     --&lt;span style="color: #0000ff"&gt;print&lt;/span&gt; &lt;span style="color: #006080"&gt;'Audit skipped for user '&lt;/span&gt; + suser_name()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum4" style="color: #606060"&gt;   4:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;return&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum5" style="color: #606060"&gt;   5:&lt;/span&gt; end&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;And that’s it. I find this way easier to manage, as typically users do not have rights to modify roles. The good practice is to have separate login for ETL from other logins, so you can audit every action that for example front end users perform, but the ETL stays almost unaffected.&lt;/p&gt;
&lt;p&gt;Please note that if you happen to be sysadmin and want to test the is_rolemember on a user defined role, it will always return 0. Quite confusing, I know. There is a &lt;a href="http://connect.microsoft.com/SQLServer/feedback/details/345809/is-member-function-does-not-work-as-expected" target="_blank"&gt;Connect item&lt;/a&gt; for IS_MEMBER function which behaves in the similar way, by design.&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:bf488679-ff78-432d-ab90-09a5b562256d" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/SQL+Server" rel="tag"&gt;SQL Server&lt;/a&gt;,&lt;a href="http://technorati.com/tags/tips+and+tricks" rel="tag"&gt;tips and tricks&lt;/a&gt;,&lt;a href="http://technorati.com/tags/code" rel="tag"&gt;code&lt;/a&gt;,&lt;a href="http://technorati.com/tags/programming" rel="tag"&gt;programming&lt;/a&gt;,&lt;a href="http://technorati.com/tags/T-SQL" rel="tag"&gt;T-SQL&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/902486075140485537-396899616345616774?l=usepubs.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=AlDzC5wEdU0:-G0cS7htO3Y:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=AlDzC5wEdU0:-G0cS7htO3Y:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=AlDzC5wEdU0:-G0cS7htO3Y:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=AlDzC5wEdU0:-G0cS7htO3Y:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=AlDzC5wEdU0:-G0cS7htO3Y:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=AlDzC5wEdU0:-G0cS7htO3Y:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=AlDzC5wEdU0:-G0cS7htO3Y:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=AlDzC5wEdU0:-G0cS7htO3Y:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=AlDzC5wEdU0:-G0cS7htO3Y:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=AlDzC5wEdU0:-G0cS7htO3Y:3QFJfmc7Om4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=AlDzC5wEdU0:-G0cS7htO3Y:3QFJfmc7Om4" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PiotrRodak/~4/AlDzC5wEdU0" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PiotrRodak/~3/AlDzC5wEdU0/disabling-audit-triggers.html</link><author>noreply@blogger.com (Piotr Rodak)</author><thr:total>0</thr:total><feedburner:origLink>http://usepubs.blogspot.com/2010/07/disabling-audit-triggers.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-902486075140485537.post-4903109979752218029</guid><pubDate>Wed, 07 Jul 2010 23:16:00 +0000</pubDate><atom:updated>2010-07-08T00:41:58.540+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">SQL Server 2008</category><category domain="http://www.blogger.com/atom/ns#">tools</category><category domain="http://www.blogger.com/atom/ns#">INSTEAD OF trigger</category><category domain="http://www.blogger.com/atom/ns#">tsql</category><category domain="http://www.blogger.com/atom/ns#">tips and tricks</category><category domain="http://www.blogger.com/atom/ns#">CREATE TRIGGER</category><category domain="http://www.blogger.com/atom/ns#">Integration Services</category><category domain="http://www.blogger.com/atom/ns#">SQL Server 2005</category><category domain="http://www.blogger.com/atom/ns#">CREATE VIEW</category><category domain="http://www.blogger.com/atom/ns#">DDL</category><category domain="http://www.blogger.com/atom/ns#">SSIS</category><category domain="http://www.blogger.com/atom/ns#">t-sql</category><category domain="http://www.blogger.com/atom/ns#">SQLServerPedia Syndication</category><title>INSTEAD OF triggers - Using views in SSIS</title><description>&lt;p&gt;This is the last post in the series about updateable views. The previous posts (&lt;a href="http://usepubs.blogspot.com/2010/06/updateable-views-how-to-use-them.html" target="_blank"&gt;Updateable views – how to use them&lt;/a&gt; and &lt;a href="http://usepubs.blogspot.com/2010/06/instead-of-triggers-on-views.html" target="_blank"&gt;INSTEAD OF triggers on views&lt;/a&gt;) described the mechanics of the views and triggers that you can use. I haven’t answered yet to question where views and triggers can be useful? &lt;/p&gt;  &lt;p&gt;The common issue that developers meet when developing SSIS packs is that there is not ‘built-in’ destination transformation that would insert rows when they don’t exist in the destination table and update rows that exist. Usually developers use a lookup and split the dataflow to OLEDB destination and OLEDB command. Adam Haines (&lt;a href="http://jahaines.blogspot.com/" target="_blank"&gt;blog&lt;/a&gt;) wrote a very nice &lt;a href="http://jahaines.blogspot.com/2009/09/sss-performing-upsert.html" target="_blank"&gt;post&lt;/a&gt; about using INSTEAD OF triggers on views to improve this solution. &lt;/p&gt;  &lt;p&gt;The other scenario I see quite interesting is logging rows that fail to be inserted into destination table. Usually failure occurs because of constraint violations – like invalid value of the column on which there is a CHECK constraint or NULL where it shouldn’t be.&lt;/p&gt;  &lt;p&gt;BCP allows for output of invalid rows into a separate file. The same sometimes is used in SSIS solutions. You can create File destination to save rows which fail to be input into the table. I see a few issues with this approach. If you use CSV file, you loose distinction between NULL and empty fields. If you use raw binary file – you can’t really investigate its contents. There is also all this hassle with destinations, file locations, disk space, access etc.&lt;/p&gt;  &lt;p&gt;I’ve been working with SSIS for a few years and in the past we came up with idea to create custom component, written in C# that would be used in script components of SSIS at the end of data flows, connected with final destinations with red arrows. This worked pretty well. In ProcessInputRow handler the row would be passed to the component which would create XML from it using reflection. The XML would subsequently be saved in a table in database, making it easy to query and troubleshoot.&lt;/p&gt;  &lt;p&gt;Well, this approach has a few drawbacks as well: you need to deploy and maintain component’s code, the error handling is processed row by row, and reflection does not improve performance, especially when upstream data were totally wrong and all rows had to be redirected to the audit output.&lt;/p&gt;  &lt;p&gt;I recently began new project, and had to approach the question of audit failed rows once more. I didn’t want to use the component due to these problems I wrote above. I realized that I can use SQL Server to convert the data from the pack into XML. Let’s look how it works.&lt;/p&gt;  &lt;p&gt;First, let’s create testing environment. We will create package that moves data from one database to another. The following snippet creates source and destination databases and table that contains the source data.&lt;/p&gt;  &lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; direction: ltr; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4; text-align: left"&gt;   &lt;div id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;     &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum1" style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;use&lt;/span&gt; master&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum2" style="color: #606060"&gt;   2:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;go&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum3" style="color: #606060"&gt;   3:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;create&lt;/span&gt; &lt;span style="color: #0000ff"&gt;database&lt;/span&gt; SSISTestSourceDB&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum4" style="color: #606060"&gt;   4:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;go&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum5" style="color: #606060"&gt;   5:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;create&lt;/span&gt; &lt;span style="color: #0000ff"&gt;database&lt;/span&gt; SSISTestDestinationDB&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum6" style="color: #606060"&gt;   6:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;go&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum7" style="color: #606060"&gt;   7:&lt;/span&gt;&amp;#160; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum8" style="color: #606060"&gt;   8:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;use&lt;/span&gt; SSISTestSourceDB&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum9" style="color: #606060"&gt;   9:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;go&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum10" style="color: #606060"&gt;  10:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;create&lt;/span&gt; &lt;span style="color: #0000ff"&gt;table&lt;/span&gt; tSource(Col1 &lt;span style="color: #0000ff"&gt;int&lt;/span&gt;, Col2 &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;, Col3 &lt;span style="color: #0000ff"&gt;varchar&lt;/span&gt;(20), Col4 datetime)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum11" style="color: #606060"&gt;  11:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;go&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum12" style="color: #606060"&gt;  12:&lt;/span&gt; insert tSource(Col1, Col2, Col3, Col4)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum13" style="color: #606060"&gt;  13:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;values&lt;/span&gt; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum14" style="color: #606060"&gt;  14:&lt;/span&gt; (1, 1, &lt;span style="color: #006080"&gt;'Value1'&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;CURRENT_TIMESTAMP&lt;/span&gt;),&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum15" style="color: #606060"&gt;  15:&lt;/span&gt; (2, &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;, &lt;span style="color: #006080"&gt;'Value1'&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;CURRENT_TIMESTAMP&lt;/span&gt;), --&lt;span style="color: #0000ff"&gt;for&lt;/span&gt; &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &lt;span style="color: #0000ff"&gt;value&lt;/span&gt; error&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum16" style="color: #606060"&gt;  16:&lt;/span&gt; (3, 3, &lt;span style="color: #006080"&gt;'DB'&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;CURRENT_TIMESTAMP&lt;/span&gt;), --&lt;span style="color: #0000ff"&gt;for&lt;/span&gt; &lt;span style="color: #0000ff"&gt;min&lt;/span&gt; length &lt;span style="color: #0000ff"&gt;check&lt;/span&gt; &lt;span style="color: #0000ff"&gt;constraint&lt;/span&gt; violation&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum17" style="color: #606060"&gt;  17:&lt;/span&gt; (4, 4, &lt;span style="color: #006080"&gt;'Value1'&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;CURRENT_TIMESTAMP&lt;/span&gt;),&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum18" style="color: #606060"&gt;  18:&lt;/span&gt; (5, 5, &lt;span style="color: #006080"&gt;'Value1'&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;CURRENT_TIMESTAMP&lt;/span&gt;),&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum19" style="color: #606060"&gt;  19:&lt;/span&gt; (6, 100, &lt;span style="color: #006080"&gt;'Value1'&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;CURRENT_TIMESTAMP&lt;/span&gt;), --&lt;span style="color: #0000ff"&gt;for&lt;/span&gt; &lt;span style="color: #0000ff"&gt;out&lt;/span&gt; &lt;span style="color: #0000ff"&gt;of&lt;/span&gt; range &lt;span style="color: #0000ff"&gt;check&lt;/span&gt; &lt;span style="color: #0000ff"&gt;constraint&lt;/span&gt; violation&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum20" style="color: #606060"&gt;  20:&lt;/span&gt; (7, 7, &lt;span style="color: #006080"&gt;'Value1'&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;CURRENT_TIMESTAMP&lt;/span&gt;),&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum21" style="color: #606060"&gt;  21:&lt;/span&gt; (8, 8, &lt;span style="color: #006080"&gt;'Value1'&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;CURRENT_TIMESTAMP&lt;/span&gt;),&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum22" style="color: #606060"&gt;  22:&lt;/span&gt; (9, 9, &lt;span style="color: #006080"&gt;'Value1'&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;CURRENT_TIMESTAMP&lt;/span&gt;),&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum23" style="color: #606060"&gt;  23:&lt;/span&gt; (10, 10, &lt;span style="color: #006080"&gt;'Value1'&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;CURRENT_TIMESTAMP&lt;/span&gt;), --two tens &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; pk violation &lt;span style="color: #0000ff"&gt;on&lt;/span&gt; destination&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum24" style="color: #606060"&gt;  24:&lt;/span&gt; (10, 11, &lt;span style="color: #006080"&gt;'Value1'&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;CURRENT_TIMESTAMP&lt;/span&gt;),&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum25" style="color: #606060"&gt;  25:&lt;/span&gt; (11, 12, &lt;span style="color: #006080"&gt;'Value1'&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;CURRENT_TIMESTAMP&lt;/span&gt;)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum26" style="color: #606060"&gt;  26:&lt;/span&gt;&amp;#160; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum27" style="color: #606060"&gt;  27:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;go&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Now let’s create table in the destination database:&lt;/p&gt;&lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 98.58%; cursor: text; direction: ltr; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; height: 189px; background-color: #f4f4f4; text-align: left"&gt;&lt;div id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum1" style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;use&lt;/span&gt; SSISTestDestinationDB&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum2" style="color: #606060"&gt;   2:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;go&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum3" style="color: #606060"&gt;   3:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;create&lt;/span&gt; &lt;span style="color: #0000ff"&gt;schema&lt;/span&gt; Staging &lt;span style="color: #0000ff"&gt;authorization&lt;/span&gt; dbo&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum4" style="color: #606060"&gt;   4:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;go&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum5" style="color: #606060"&gt;   5:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;create&lt;/span&gt; &lt;span style="color: #0000ff"&gt;table&lt;/span&gt; Staging.tDestination &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum6" style="color: #606060"&gt;   6:&lt;/span&gt; (&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum7" style="color: #606060"&gt;   7:&lt;/span&gt;     Col1 &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; &lt;span style="color: #0000ff"&gt;not&lt;/span&gt; &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &lt;span style="color: #0000ff"&gt;constraint&lt;/span&gt; PK__1 &lt;span style="color: #0000ff"&gt;primary&lt;/span&gt; &lt;span style="color: #0000ff"&gt;key&lt;/span&gt; &lt;span style="color: #0000ff"&gt;clustered&lt;/span&gt;,&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum8" style="color: #606060"&gt;   8:&lt;/span&gt;     Col2 &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; &lt;span style="color: #0000ff"&gt;not&lt;/span&gt; &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &lt;span style="color: #0000ff"&gt;constraint&lt;/span&gt; CHK__Col2_Range &lt;span style="color: #0000ff"&gt;check&lt;/span&gt; (Col2 &amp;lt; 30),&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum9" style="color: #606060"&gt;   9:&lt;/span&gt;     Col3 &lt;span style="color: #0000ff"&gt;varchar&lt;/span&gt;(20) &lt;span style="color: #0000ff"&gt;not&lt;/span&gt; &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &lt;span style="color: #0000ff"&gt;constraint&lt;/span&gt; CHK__MinLenGreaterThan2 &lt;span style="color: #0000ff"&gt;check&lt;/span&gt; (len(Col3) &amp;gt; 2),&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum10" style="color: #606060"&gt;  10:&lt;/span&gt;     Col4 datetime &lt;span style="color: #0000ff"&gt;not&lt;/span&gt; &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum11" style="color: #606060"&gt;  11:&lt;/span&gt; ) &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum12" style="color: #606060"&gt;  12:&lt;/span&gt; go&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;The Audit table will store the audit data:&lt;/p&gt;&lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; direction: ltr; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4; text-align: left"&gt;&lt;div id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum1" style="color: #606060"&gt;   1:&lt;/span&gt; --&lt;span style="color: #0000ff"&gt;table&lt;/span&gt; that will accept errors &lt;span style="color: #0000ff"&gt;from&lt;/span&gt; the pack&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum2" style="color: #606060"&gt;   2:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;create&lt;/span&gt; &lt;span style="color: #0000ff"&gt;table&lt;/span&gt; Audit.tAuditETLErrors&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum3" style="color: #606060"&gt;   3:&lt;/span&gt; (&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum4" style="color: #606060"&gt;   4:&lt;/span&gt;     [ErrorCode] [bigint] &lt;span style="color: #0000ff"&gt;NULL&lt;/span&gt;,&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum5" style="color: #606060"&gt;   5:&lt;/span&gt;     [ErrorColumn] [bigint] &lt;span style="color: #0000ff"&gt;NULL&lt;/span&gt;,&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum6" style="color: #606060"&gt;   6:&lt;/span&gt;     [ErrorDescription] [nvarchar](1000) &lt;span style="color: #0000ff"&gt;NULL&lt;/span&gt;,&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum7" style="color: #606060"&gt;   7:&lt;/span&gt;     [ErrorData] [xml] &lt;span style="color: #0000ff"&gt;NULL&lt;/span&gt;, --actual &lt;span style="color: #0000ff"&gt;row&lt;/span&gt; &lt;span style="color: #0000ff"&gt;data&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum8" style="color: #606060"&gt;   8:&lt;/span&gt;     [UpdateDate] [datetime] &lt;span style="color: #0000ff"&gt;not&lt;/span&gt; &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &lt;span style="color: #0000ff"&gt;constraint&lt;/span&gt; DF_UpdateDate1 &lt;span style="color: #0000ff"&gt;default&lt;/span&gt; (getdate())&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum9" style="color: #606060"&gt;   9:&lt;/span&gt; )&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum10" style="color: #606060"&gt;  10:&lt;/span&gt; go&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;As you see, the table is pretty simple: ErrorCode and ErrorColumn are derived directly from data flow in the SSIS package, ErrorDescription is added to retrieve more meaningful error description and ErrorData is XML column that contains serialized audit row.&lt;/p&gt;&lt;p&gt;Now the main part of the idea: a view with an INSTEAD OF INSERT trigger on it.&lt;/p&gt;&lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; direction: ltr; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4; text-align: left"&gt;&lt;div id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum1" style="color: #606060"&gt;   1:&lt;/span&gt; --&lt;span style="color: #0000ff"&gt;create&lt;/span&gt; error handling &lt;span style="color: #0000ff"&gt;view&lt;/span&gt; &lt;span style="color: #0000ff"&gt;and&lt;/span&gt; &lt;span style="color: #0000ff"&gt;trigger&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum2" style="color: #606060"&gt;   2:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;create&lt;/span&gt; &lt;span style="color: #0000ff"&gt;view&lt;/span&gt; Audit.vDestinationSSISError&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum3" style="color: #606060"&gt;   3:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;as&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum4" style="color: #606060"&gt;   4:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;select&lt;/span&gt; &lt;span style="color: #0000ff"&gt;convert&lt;/span&gt;(bigint, 0) ErrorCode, &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum5" style="color: #606060"&gt;   5:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;convert&lt;/span&gt;(bigint, 0) ErrorColumn, &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum6" style="color: #606060"&gt;   6:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;convert&lt;/span&gt;(nvarchar(1000), N&lt;span style="color: #006080"&gt;''&lt;/span&gt;) ErrorDescription, &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum7" style="color: #606060"&gt;   7:&lt;/span&gt;         dst.* &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum8" style="color: #606060"&gt;   8:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;from&lt;/span&gt; Staging.tDestination dst&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum9" style="color: #606060"&gt;   9:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;where&lt;/span&gt; 1 = 0 --this &lt;span style="color: #0000ff"&gt;view&lt;/span&gt; doesn&lt;span style="color: #006080"&gt;'t have to return any data&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum10" style="color: #606060"&gt;  10:&lt;/span&gt; go&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum11" style="color: #606060"&gt;  11:&lt;/span&gt; create trigger Audit.trgins_vDestinationSSISError on Audit.vDestinationSSISError&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum12" style="color: #606060"&gt;  12:&lt;/span&gt; instead of insert&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum13" style="color: #606060"&gt;  13:&lt;/span&gt; as&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum14" style="color: #606060"&gt;  14:&lt;/span&gt; begin&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum15" style="color: #606060"&gt;  15:&lt;/span&gt;     set nocount on&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum16" style="color: #606060"&gt;  16:&lt;/span&gt;     --insert new row to audit table. actual data are converted to XML&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum17" style="color: #606060"&gt;  17:&lt;/span&gt;     insert Audit.tAuditETLErrors (ErrorCode, ErrorColumn, ErrorDescription, ErrorData, UpdateDate)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum18" style="color: #606060"&gt;  18:&lt;/span&gt;     select ErrorCode, ErrorColumn, ErrorDescription, &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum19" style="color: #606060"&gt;  19:&lt;/span&gt;     (select * from inserted &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum20" style="color: #606060"&gt;  20:&lt;/span&gt;         for xml raw, elements xsinil, root('&lt;/span&gt;etl_error')), &lt;span style="color: #0000ff"&gt;current_timestamp&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum21" style="color: #606060"&gt;  21:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;from&lt;/span&gt; inserted&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum22" style="color: #606060"&gt;  22:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; text-align: left; border-bottom-style: none"&gt;&lt;span id="lnum23" style="color: #606060"&gt;  23:&lt;/span&gt; go&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The view doesn’t return any data, because in this case it is used only for trigger. The view has to expose ErrorCode, ErrorColumn and ErrorDescription columns, plus &lt;strong&gt;all columns&lt;/strong&gt; of the destination table if you want to audit all columns.&lt;/p&gt;&lt;p&gt;The trigger uses select… for xml query to serialize incoming data into xml stream that is inserted eventually to ErrorData column.&lt;/p&gt;&lt;p&gt;The package is built in pretty simple way. There is OLEDB source, OLEDB destination – using ‘fast’ bulk load option. Then there is OLEDB ‘Normal’ destination – for batches which were rolled back because of errors in the ‘Fast’ destination. &lt;/p&gt;&lt;p&gt;&lt;a href="http://lh5.ggpht.com/_ZwcS80etW1Q/TDUKxIYH0eI/AAAAAAAAACM/3MSJJfadJjg/s1600-h/screenshot47%5B2%5D.jpg"&gt;&lt;img title="screenshot47" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="224" alt="screenshot47" src="http://lh6.ggpht.com/_ZwcS80etW1Q/TDUKxgdqNDI/AAAAAAAAACQ/ncPVDRH5voE/screenshot47_thumb.jpg?imgmax=800" width="244" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Then, for rows that didn’t make it to the destination table, redirection to additional destination is made, to the view destination:&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;a href="http://lh5.ggpht.com/_ZwcS80etW1Q/TDUKyLXD1-I/AAAAAAAAACU/-eUINXvajMc/s1600-h/screenshot51%5B2%5D.jpg"&gt;&lt;img title="screenshot51" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="159" alt="screenshot51" src="http://lh6.ggpht.com/_ZwcS80etW1Q/TDUKyUXTVgI/AAAAAAAAACY/gTiXY5UOIYE/screenshot51_thumb.jpg?imgmax=800" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;The script component before the final destination adds ErrorDescription to the data flow:&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh4.ggpht.com/_ZwcS80etW1Q/TDUKy_zfL7I/AAAAAAAAACc/TEDwPjUP2sc/s1600-h/screenshot49%5B2%5D.jpg"&gt;&lt;img title="screenshot49" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="124" alt="screenshot49" src="http://lh4.ggpht.com/_ZwcS80etW1Q/TDUKzaTZY2I/AAAAAAAAACg/5zjy7HlSrIA/screenshot49_thumb.jpg?imgmax=800" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;a href="http://lh3.ggpht.com/_ZwcS80etW1Q/TDUKz80ePcI/AAAAAAAAACk/g3F47si_KO0/s1600-h/screenshot50%5B2%5D.jpg"&gt;&lt;img title="screenshot50" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="123" alt="screenshot50" src="http://lh3.ggpht.com/_ZwcS80etW1Q/TDUK0q9THVI/AAAAAAAAACo/mI6t8kwxArc/screenshot50_thumb.jpg?imgmax=800" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;There’s a catch: you better use ADO.NET destination in the package because OLEDB destination is unaware of the triggers on the views. While you can configure OLEDB destination to use view, the rows will fail to be inserted because of the same reasons they weren’t inserted in the fist place. You can solve it by creating a table with exactly the same schema as the destination table but without any constraints. This approach is a bit awkward and you have to maintain tables in sync. I found it easier to use ADO.NET destination. If you use connection string stored in package configurations, you just have to be sure that you use connection string for .NET for this destination, otherwise it will not work.&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh6.ggpht.com/_ZwcS80etW1Q/TDUK1HPsUyI/AAAAAAAAACs/ZMbqUgnl9iQ/s1600-h/screenshot48%5B2%5D.jpg"&gt;&lt;img title="screenshot48" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="66" alt="screenshot48" src="http://lh5.ggpht.com/_ZwcS80etW1Q/TDUK1YnaKSI/AAAAAAAAACw/xf4eUThVXSI/screenshot48_thumb.jpg?imgmax=800" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;You map the columns the normal way:&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh5.ggpht.com/_ZwcS80etW1Q/TDUK1wr8CBI/AAAAAAAAAC0/u2IlFSD1EK8/s1600-h/screenshot52%5B2%5D.jpg"&gt;&lt;img title="screenshot52" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="106" alt="screenshot52" src="http://lh6.ggpht.com/_ZwcS80etW1Q/TDUK260haBI/AAAAAAAAAC4/2x04sE3EY7Q/screenshot52_thumb.jpg?imgmax=800" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;This is what you’ll see when you run the package:&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh6.ggpht.com/_ZwcS80etW1Q/TDUK3J4cYiI/AAAAAAAAAC8/UKExNS-q_88/s1600-h/screenshot56%5B2%5D.jpg"&gt;&lt;img title="screenshot56" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="screenshot56" src="http://lh3.ggpht.com/_ZwcS80etW1Q/TDUK3v_vajI/AAAAAAAAADA/yINloxx8ATY/screenshot56_thumb.jpg?imgmax=800" width="243" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;From 12 rows read from the source, three were inserted using bulk insert, and nine went to the ‘Slow’ destination. There, rows were inserted row by row, and rows which failed were redirected to the error output – you see there were four of them. Then the script component adds ErrorDescription column and rows are inserted into the view. When you select from the Audit.tAuditETLErrors table you will see all four of them:&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh5.ggpht.com/_ZwcS80etW1Q/TDUK4TqqIkI/AAAAAAAAADE/sDC2d2SKUOo/s1600-h/screenshot57%5B2%5D.jpg"&gt;&lt;img title="screenshot57" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="60" alt="screenshot57" src="http://lh5.ggpht.com/_ZwcS80etW1Q/TDUK4jp182I/AAAAAAAAADI/-8U8vvnoMwI/screenshot57_thumb.jpg?imgmax=800" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;I find this setup pretty useful, I wonder what do you think.&lt;/p&gt;&lt;p&gt;I attach the &lt;a href="https://docs.google.com/uc?id=0B5ayjYKh-6TxNGExODhmNzgtOTI1MC00ZjBkLTgwMzgtNDUwOWJkMjZmMDJm&amp;amp;export=download&amp;amp;hl=en" target="_blank"&gt;test script&lt;/a&gt; and the &lt;a href="https://docs.google.com/uc?id=0B5ayjYKh-6TxMTI0YzU5ZmUtYmRiNC00M2NiLWI3MTItMWEwNTkwNDBjNDUx&amp;amp;export=download&amp;amp;hl=en" target="_blank"&gt;test SSIS project&lt;/a&gt; so you can straight go to the fun part.&lt;/p&gt;&lt;div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:a3e2833a-4443-40e0-9bf3-dcbae2313c59" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/SQL+Server+2008" rel="tag"&gt;SQL Server 2008&lt;/a&gt;,&lt;a href="http://technorati.com/tags/SQL+Server+2005" rel="tag"&gt;SQL Server 2005&lt;/a&gt;,&lt;a href="http://technorati.com/tags/T-SQL" rel="tag"&gt;T-SQL&lt;/a&gt;,&lt;a href="http://technorati.com/tags/TSQL" rel="tag"&gt;TSQL&lt;/a&gt;,&lt;a href="http://technorati.com/tags/SQL" rel="tag"&gt;SQL&lt;/a&gt;,&lt;a href="http://technorati.com/tags/programming" rel="tag"&gt;programming&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Tips+and+tricks" rel="tag"&gt;Tips and tricks&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/902486075140485537-4903109979752218029?l=usepubs.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=kDT5GYGVc30:HFlveWLvFnM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=kDT5GYGVc30:HFlveWLvFnM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=kDT5GYGVc30:HFlveWLvFnM:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=kDT5GYGVc30:HFlveWLvFnM:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=kDT5GYGVc30:HFlveWLvFnM:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=kDT5GYGVc30:HFlveWLvFnM:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=kDT5GYGVc30:HFlveWLvFnM:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=kDT5GYGVc30:HFlveWLvFnM:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=kDT5GYGVc30:HFlveWLvFnM:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=kDT5GYGVc30:HFlveWLvFnM:3QFJfmc7Om4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=kDT5GYGVc30:HFlveWLvFnM:3QFJfmc7Om4" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PiotrRodak/~4/kDT5GYGVc30" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PiotrRodak/~3/kDT5GYGVc30/instead-of-triggers-using-views-in-ssis.html</link><author>noreply@blogger.com (Piotr Rodak)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/_ZwcS80etW1Q/TDUKxgdqNDI/AAAAAAAAACQ/ncPVDRH5voE/s72-c/screenshot47_thumb.jpg?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://usepubs.blogspot.com/2010/07/instead-of-triggers-using-views-in-ssis.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-902486075140485537.post-4779799998556714889</guid><pubDate>Sun, 27 Jun 2010 23:07:00 +0000</pubDate><atom:updated>2010-06-28T00:11:47.782+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">tools</category><category domain="http://www.blogger.com/atom/ns#">tsql</category><category domain="http://www.blogger.com/atom/ns#">INSTEAD OF trigger</category><category domain="http://www.blogger.com/atom/ns#">tips and tricks</category><category domain="http://www.blogger.com/atom/ns#">CREATE TRIGGER</category><category domain="http://www.blogger.com/atom/ns#">DDL</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#">AdventureWorks</category><category domain="http://www.blogger.com/atom/ns#">SQLServerPedia Syndication</category><category domain="http://www.blogger.com/atom/ns#">code</category><category domain="http://www.blogger.com/atom/ns#">constraints</category><category domain="http://www.blogger.com/atom/ns#">programming</category><category domain="http://www.blogger.com/atom/ns#">script</category><title>INSTEAD OF triggers on views</title><description>Last time I wrote about &lt;a href="http://usepubs.blogspot.com/2010/06/updateable-views-how-to-use-them.html" target="_blank"&gt;updateable views&lt;/a&gt; – a feature that is not considered by many database architects and developers when they implement data interface. The updateable views have some limitations what makes them useful in only specific situations. Two most important limitations in my opinion are that you cannot update columns from more than one table in single update statement and that any derived or calculated columns cannot be directly updated. &lt;br /&gt;
Luckily, there is a way to bypass these limitations by using INDSTEAD OF triggers on views. The triggers are fired as the name implies &lt;b&gt;instead of&lt;/b&gt; DML statement, so you have to implement effective operation within the trigger. If the trigger is empty, no update, insert or delete will be made.&lt;br /&gt;
Let’s look at Person.vContact2 view again. The view returns columns ContactId, NameStyle, &lt;b&gt;Full Title&lt;/b&gt;, FirstName, MiddleName, LastName and several others. The Full Title column is a column that returns custom information depending on the underlying Title column from the Person.Contact table. You cannot update the Full Title column directly, because it doesn’t exist in the Person.Contact. If you want to change the information returned by the view, you have to modify the Title column in the table. Of course, you can update the table directly or via stored procedure and in most cases this would be the preferred way, but in some cases updating the view has its benefits. You may also have a requirement that the tables must not be updateable directly and the views are the only interface you can use to modify the data.&lt;br /&gt;
So, to change the Full Title column in the view, you have to modify the Title value appropriately. As you remember, the definition of the view is as follows:&lt;br /&gt;
&lt;div class="csharpcode-wrapper" id="codeSnippetWrapper"&gt;&lt;div class="csharpcode" id="codeSnippet"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;ALTER&lt;/span&gt; &lt;span class="kwrd"&gt;view&lt;/span&gt; [Person].[vContact2]&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span class="kwrd"&gt;as&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum3"&gt;   3:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; ContactID, NameStyle, &lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum4"&gt;   4:&lt;/span&gt; &lt;span class="kwrd"&gt;case&lt;/span&gt; &lt;span class="kwrd"&gt;when&lt;/span&gt; Title = &lt;span class="str"&gt;'Mr.'&lt;/span&gt; &lt;span class="kwrd"&gt;then&lt;/span&gt; &lt;span class="str"&gt;'Very long title 1'&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum5"&gt;   5:&lt;/span&gt;     &lt;span class="kwrd"&gt;when&lt;/span&gt; Title = &lt;span class="str"&gt;'Ms.'&lt;/span&gt; &lt;span class="kwrd"&gt;then&lt;/span&gt; &lt;span class="str"&gt;'Very long title 2'&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum6"&gt;   6:&lt;/span&gt;     &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="str"&gt;'Other title'&lt;/span&gt; &lt;span class="kwrd"&gt;end&lt;/span&gt; [&lt;span class="kwrd"&gt;Full&lt;/span&gt; Title], &lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum7"&gt;   7:&lt;/span&gt; FirstName, MiddleName, LastName, Suffix, EmailAddress, EmailPromotion, Phone, PasswordHash, PasswordSalt, rowguid, ModifiedDate&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum8"&gt;   8:&lt;/span&gt; &lt;span class="kwrd"&gt;from&lt;/span&gt; Person.Contact&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;br /&gt;
Lines 4-6 contain definition of the Full Title column. In my AdventureWorks database, ContactID has ‘Other title’ returned by the view. I want to change it to ‘Very long title 1’.&lt;br /&gt;
&lt;br /&gt;
You can create triggers for INSERT, UPDATE and DELETE statements. One of the ways is to create one trigger for all three types of operation, the other is to create a separate trigger for each of types separately. The latter approach simplifies logic within the trigger a bit, on the expense of maintainability – you have three database objects to worry about instead of one.&lt;br /&gt;
&lt;br /&gt;
This is sample trigger that is fired for every DML operation against the view:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="csharpcode-wrapper" id="codeSnippetWrapper"&gt;&lt;div class="csharpcode" id="codeSnippet"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;create&lt;/span&gt; &lt;span class="kwrd"&gt;trigger&lt;/span&gt; Person.trgVContact2 &lt;span class="kwrd"&gt;on&lt;/span&gt; Person.vContact2&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum2"&gt;   2:&lt;/span&gt; instead &lt;span class="kwrd"&gt;of&lt;/span&gt; insert, &lt;span class="kwrd"&gt;update&lt;/span&gt;, &lt;span class="kwrd"&gt;delete&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum3"&gt;   3:&lt;/span&gt; &lt;span class="kwrd"&gt;as&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum4"&gt;   4:&lt;/span&gt; &lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum5"&gt;   5:&lt;/span&gt;     &lt;span class="kwrd"&gt;print&lt;/span&gt; &lt;span class="str"&gt;'Trigger called'&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum6"&gt;   6:&lt;/span&gt; &lt;span class="kwrd"&gt;end&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;br /&gt;
Now let’s call an update on the view:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="csharpcode-wrapper" id="codeSnippetWrapper"&gt;
&lt;div class="csharpcode" id="codeSnippet"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; * &lt;span class="kwrd"&gt;from&lt;/span&gt; Person.vContact2 &lt;span class="kwrd"&gt;where&lt;/span&gt; ContactId = 4&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span class="kwrd"&gt;update&lt;/span&gt; Person.vContact2 &lt;span class="kwrd"&gt;set&lt;/span&gt; LastName = &lt;span class="str"&gt;'NoName'&lt;/span&gt; &lt;span class="kwrd"&gt;where&lt;/span&gt; ContactId = 4&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum3"&gt;   3:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; * &lt;span class="kwrd"&gt;from&lt;/span&gt; Person.vContact2 &lt;span class="kwrd"&gt;where&lt;/span&gt; ContactId = 4&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
Nice. The trigger was fired as you can see in the output. But, if you look at the LastName column, &lt;b&gt;it was not changed&lt;/b&gt;. This is because this is an &lt;b&gt;instead of&lt;/b&gt; trigger and it &lt;b&gt;replaces&lt;/b&gt; the original operation. To actually update the column,&amp;nbsp; you have to implement the trigger in more useful way:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="csharpcode-wrapper" id="codeSnippetWrapper"&gt;
&lt;div class="csharpcode" id="codeSnippet"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; &lt;span class="kwrd"&gt;exists&lt;/span&gt; (&lt;span class="kwrd"&gt;select&lt;/span&gt; 1 &lt;span class="kwrd"&gt;from&lt;/span&gt; sys.objects &lt;span class="kwrd"&gt;where&lt;/span&gt; object_id = object_id(&lt;span class="str"&gt;'Person.trgVContact2'&lt;/span&gt;))&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span class="kwrd"&gt;drop&lt;/span&gt; &lt;span class="kwrd"&gt;trigger&lt;/span&gt; Person.trgVContact2&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum3"&gt;   3:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum4"&gt;   4:&lt;/span&gt; &lt;span class="kwrd"&gt;create&lt;/span&gt; &lt;span class="kwrd"&gt;trigger&lt;/span&gt; Person.trgVContact2 &lt;span class="kwrd"&gt;on&lt;/span&gt; Person.vContact2&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum5"&gt;   5:&lt;/span&gt; instead &lt;span class="kwrd"&gt;of&lt;/span&gt; insert, &lt;span class="kwrd"&gt;update&lt;/span&gt;, &lt;span class="kwrd"&gt;delete&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum6"&gt;   6:&lt;/span&gt; &lt;span class="kwrd"&gt;as&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum7"&gt;   7:&lt;/span&gt; &lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum8"&gt;   8:&lt;/span&gt;     &lt;span class="kwrd"&gt;if&lt;/span&gt; (@@&lt;span class="kwrd"&gt;rowcount&lt;/span&gt; = 0)&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum9"&gt;   9:&lt;/span&gt;     &lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum10"&gt;  10:&lt;/span&gt;         &lt;span class="kwrd"&gt;print&lt;/span&gt; &lt;span class="str"&gt;'No rows matching criteria'&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum11"&gt;  11:&lt;/span&gt;         &lt;span class="kwrd"&gt;return&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum12"&gt;  12:&lt;/span&gt;     &lt;span class="kwrd"&gt;end&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum13"&gt;  13:&lt;/span&gt;     &lt;span class="kwrd"&gt;if&lt;/span&gt; &lt;span class="kwrd"&gt;exists&lt;/span&gt;(&lt;span class="kwrd"&gt;select&lt;/span&gt; 1 &lt;span class="kwrd"&gt;from&lt;/span&gt; inserted) &lt;span class="kwrd"&gt;and&lt;/span&gt; &lt;span class="kwrd"&gt;exists&lt;/span&gt; (&lt;span class="kwrd"&gt;select&lt;/span&gt; 1 &lt;span class="kwrd"&gt;from&lt;/span&gt; deleted) --&lt;span class="kwrd"&gt;update&lt;/span&gt; operationr&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum14"&gt;  14:&lt;/span&gt;     &lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum15"&gt;  15:&lt;/span&gt;         &lt;span class="kwrd"&gt;update&lt;/span&gt; contacts &lt;span class="kwrd"&gt;set&lt;/span&gt; LastName = inserted.LastName&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum16"&gt;  16:&lt;/span&gt;         &lt;span class="kwrd"&gt;from&lt;/span&gt; Person.Contact contacts &lt;span class="kwrd"&gt;inner&lt;/span&gt; &lt;span class="kwrd"&gt;join&lt;/span&gt; inserted &lt;span class="kwrd"&gt;on&lt;/span&gt; contacts.ContactId = inserted.ContactId &lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum17"&gt;  17:&lt;/span&gt;     &lt;span class="kwrd"&gt;end&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum18"&gt;  18:&lt;/span&gt;     &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; &lt;span class="kwrd"&gt;exists&lt;/span&gt;(&lt;span class="kwrd"&gt;select&lt;/span&gt; 1 &lt;span class="kwrd"&gt;from&lt;/span&gt; inserted) --insert &lt;span class="kwrd"&gt;operation&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum19"&gt;  19:&lt;/span&gt;     &lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum20"&gt;  20:&lt;/span&gt;         &lt;span class="kwrd"&gt;return&lt;/span&gt;; --TODO: implement &lt;span class="kwrd"&gt;with&lt;/span&gt; useful logic&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum21"&gt;  21:&lt;/span&gt;     &lt;span class="kwrd"&gt;end&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum22"&gt;  22:&lt;/span&gt;     &lt;span class="kwrd"&gt;else&lt;/span&gt; --&lt;span class="kwrd"&gt;delete&lt;/span&gt; &lt;span class="kwrd"&gt;operation&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum23"&gt;  23:&lt;/span&gt;     &lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum24"&gt;  24:&lt;/span&gt;         &lt;span class="kwrd"&gt;return&lt;/span&gt;; --TODO: implement &lt;span class="kwrd"&gt;with&lt;/span&gt; useful logic&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum25"&gt;  25:&lt;/span&gt;     &lt;span class="kwrd"&gt;end&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum26"&gt;  26:&lt;/span&gt; &lt;span class="kwrd"&gt;end&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
As you see, this trigger allows for updating only LastName column. This column this column is exposed by the view without any modifications. On a side, did you know that triggers are fired even when no rows are affected? This was a surprise for me a few months ago. You can prevent potentially costly code from running if you check if there is anything to process. Lines 8-12 show how it can be done.&lt;br /&gt;
&lt;br /&gt;
Ok, what about Full Title and other columns? This is the modified code for update operation only:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="csharpcode-wrapper" id="codeSnippetWrapper"&gt;
&lt;div class="csharpcode" id="codeSnippet"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; &lt;span class="kwrd"&gt;exists&lt;/span&gt;(&lt;span class="kwrd"&gt;select&lt;/span&gt; 1 &lt;span class="kwrd"&gt;from&lt;/span&gt; inserted) &lt;span class="kwrd"&gt;and&lt;/span&gt; &lt;span class="kwrd"&gt;exists&lt;/span&gt; (&lt;span class="kwrd"&gt;select&lt;/span&gt; 1 &lt;span class="kwrd"&gt;from&lt;/span&gt; deleted) --&lt;span class="kwrd"&gt;update&lt;/span&gt; operationr&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum2"&gt;   2:&lt;/span&gt;     &lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum3"&gt;   3:&lt;/span&gt;         &lt;span class="kwrd"&gt;if&lt;/span&gt; &lt;span class="kwrd"&gt;update&lt;/span&gt;(PasswordHash) &lt;span class="kwrd"&gt;or&lt;/span&gt; &lt;span class="kwrd"&gt;update&lt;/span&gt;(PasswordSalt)&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum4"&gt;   4:&lt;/span&gt;         &lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum5"&gt;   5:&lt;/span&gt;             &lt;span class="kwrd"&gt;print&lt;/span&gt; &lt;span class="str"&gt;'Password data changes are not permitted'&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum6"&gt;   6:&lt;/span&gt;             &lt;span class="kwrd"&gt;return&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum7"&gt;   7:&lt;/span&gt;         &lt;span class="kwrd"&gt;end&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum8"&gt;   8:&lt;/span&gt;         &lt;span class="kwrd"&gt;update&lt;/span&gt; contacts &lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum9"&gt;   9:&lt;/span&gt;             &lt;span class="kwrd"&gt;set&lt;/span&gt; NameStyle = inserted.NameStyle,&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum10"&gt;  10:&lt;/span&gt;                 Title = &lt;span class="kwrd"&gt;case&lt;/span&gt; inserted.[&lt;span class="kwrd"&gt;Full&lt;/span&gt; Title]&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum11"&gt;  11:&lt;/span&gt;                             &lt;span class="kwrd"&gt;when&lt;/span&gt; &lt;span class="str"&gt;'Very long title 1'&lt;/span&gt; &lt;span class="kwrd"&gt;then&lt;/span&gt; &lt;span class="str"&gt;'Mr.'&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum12"&gt;  12:&lt;/span&gt;                             &lt;span class="kwrd"&gt;when&lt;/span&gt; &lt;span class="str"&gt;'Very long title 2'&lt;/span&gt; &lt;span class="kwrd"&gt;then&lt;/span&gt; &lt;span class="str"&gt;'Ms.'&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum13"&gt;  13:&lt;/span&gt;                             &lt;span class="kwrd"&gt;else&lt;/span&gt; contacts.Title --&lt;span class="kwrd"&gt;no&lt;/span&gt; change &lt;span class="kwrd"&gt;in&lt;/span&gt; this &lt;span class="kwrd"&gt;case&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum14"&gt;  14:&lt;/span&gt;                         &lt;span class="kwrd"&gt;end&lt;/span&gt;,&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum15"&gt;  15:&lt;/span&gt;                 FirstName = inserted.FirstName,&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum16"&gt;  16:&lt;/span&gt;                 MiddleName = inserted.MiddleName,&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum17"&gt;  17:&lt;/span&gt;                 LastName = inserted.LastName,&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum18"&gt;  18:&lt;/span&gt;                 Suffix = inserted.Suffix,&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum19"&gt;  19:&lt;/span&gt;                 EmailAddress = inserted.EmailAddress,&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum20"&gt;  20:&lt;/span&gt;                 EmailPromotion = inserted.EmailPromotion,&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum21"&gt;  21:&lt;/span&gt;                 Phone = inserted.Phone,&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum22"&gt;  22:&lt;/span&gt;                 ModifiedDate = &lt;span class="kwrd"&gt;current_timestamp&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum23"&gt;  23:&lt;/span&gt;         &lt;span class="kwrd"&gt;from&lt;/span&gt; Person.Contact contacts &lt;span class="kwrd"&gt;inner&lt;/span&gt; &lt;span class="kwrd"&gt;join&lt;/span&gt; inserted &lt;span class="kwrd"&gt;on&lt;/span&gt; contacts.ContactId = inserted.ContactId &lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum24"&gt;  24:&lt;/span&gt;     end&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
Triggers offer you opportunity to validate what columns are updated. In certain scenarios, you don’t want users to be able to modify sensitive data. This can be achieved using triggers for example. In lines 3-7 of the above script you can see code preventing update operation on PasswordSalt and PasswordHash operations.&lt;br /&gt;
&lt;br /&gt;
Ok, so far, so good. Triggers on views are one of the methods of implementing logic required to update data. However usually it is better to do it using stored procedures. There are scenarios though when triggers on views give you quite interesting ways of implementing ETL. More about this in next post.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:d3c3a7e9-700a-4b19-b917-46ecef8816df" style="display: inline; float: none; margin: 0px; padding: 0px;"&gt;
Technorati Tags: &lt;a href="http://technorati.com/tags/sql+server" rel="tag"&gt;sql server&lt;/a&gt;,&lt;a href="http://technorati.com/tags/programming" rel="tag"&gt;programming&lt;/a&gt;,&lt;a href="http://technorati.com/tags/trigger" rel="tag"&gt;trigger&lt;/a&gt;,&lt;a href="http://technorati.com/tags/DDL" rel="tag"&gt;DDL&lt;/a&gt;,&lt;a href="http://technorati.com/tags/DML" rel="tag"&gt;DML&lt;/a&gt;,&lt;a href="http://technorati.com/tags/t-sql" rel="tag"&gt;t-sql&lt;/a&gt;,&lt;a href="http://technorati.com/tags/code" rel="tag"&gt;code&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/902486075140485537-4779799998556714889?l=usepubs.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=NCXN4lBJQnI:fE3FrcTu0iE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=NCXN4lBJQnI:fE3FrcTu0iE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=NCXN4lBJQnI:fE3FrcTu0iE:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=NCXN4lBJQnI:fE3FrcTu0iE:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=NCXN4lBJQnI:fE3FrcTu0iE:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=NCXN4lBJQnI:fE3FrcTu0iE:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=NCXN4lBJQnI:fE3FrcTu0iE:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=NCXN4lBJQnI:fE3FrcTu0iE:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=NCXN4lBJQnI:fE3FrcTu0iE:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=NCXN4lBJQnI:fE3FrcTu0iE:3QFJfmc7Om4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=NCXN4lBJQnI:fE3FrcTu0iE:3QFJfmc7Om4" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PiotrRodak/~4/NCXN4lBJQnI" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PiotrRodak/~3/NCXN4lBJQnI/instead-of-triggers-on-views.html</link><author>noreply@blogger.com (Piotr Rodak)</author><thr:total>8</thr:total><feedburner:origLink>http://usepubs.blogspot.com/2010/06/instead-of-triggers-on-views.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-902486075140485537.post-4113367191299684378</guid><pubDate>Mon, 21 Jun 2010 22:29:00 +0000</pubDate><atom:updated>2010-06-22T22:46:52.033+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">INSTEAD OF trigger</category><category domain="http://www.blogger.com/atom/ns#">tsql</category><category domain="http://www.blogger.com/atom/ns#">tips and tricks</category><category domain="http://www.blogger.com/atom/ns#">execution plan</category><category domain="http://www.blogger.com/atom/ns#">CREATE VIEW</category><category domain="http://www.blogger.com/atom/ns#">DDL</category><category domain="http://www.blogger.com/atom/ns#">t-sql</category><category domain="http://www.blogger.com/atom/ns#">AdventureWorks</category><category domain="http://www.blogger.com/atom/ns#">SQLServerPedia Syndication</category><category domain="http://www.blogger.com/atom/ns#">code</category><category domain="http://www.blogger.com/atom/ns#">constraints</category><category domain="http://www.blogger.com/atom/ns#">programming</category><category domain="http://www.blogger.com/atom/ns#">script</category><title>Updateable views – how to use them</title><description>This post is first part of miniseries that discusses ways of updating data in views. In this post I will discuss updateable views, in the second part there will be short overview of INSTEAD OF triggers and interesting implications they offer.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note: All examples in this post are made using AdventureWorks sample database, which you can download from &lt;/b&gt;&lt;a href="http://msftdbprodsamples.codeplex.com/releases/view/4004" target="_blank"&gt;&lt;b&gt;CodePlex page&lt;/b&gt;&lt;/a&gt;&lt;b&gt;.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
With simple views selecting just from single table, with no derived columns the query engine knows how to translate insert or update statement on view to appropriate operation on underlying tables, and no trigger is required. The following script shows an example of such behaviour:&lt;br /&gt;
&lt;br /&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div class="csharpcode" id="codeSnippet"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; * &lt;span class="kwrd"&gt;from&lt;/span&gt; Person.vContact1 &lt;span class="kwrd"&gt;where&lt;/span&gt; ContactID = 1&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span class="kwrd"&gt;update&lt;/span&gt; Person.vContact1 &lt;span class="kwrd"&gt;set&lt;/span&gt; MiddleName = &lt;span class="str"&gt;'S.'&lt;/span&gt; &lt;span class="kwrd"&gt;where&lt;/span&gt; ContactID = 1&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum3"&gt;   3:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; * &lt;span class="kwrd"&gt;from&lt;/span&gt; Person.vContact1 &lt;span class="kwrd"&gt;where&lt;/span&gt; ContactID = 1&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
The query engine translates update statement against the view to an update statement against the underlying table, and if you look at the execution plan of the update statement, you’ll see there is no difference to an update statement against the bare table:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://lh4.ggpht.com/_ZwcS80etW1Q/TB_n2nOGlxI/AAAAAAAAACE/QMVV28KZ7xI/s1600-h/viewupdate1%5B2%5D.jpg"&gt;&lt;img alt="viewupdate1" border="0" height="38" src="http://lh4.ggpht.com/_ZwcS80etW1Q/TB_n2w5F57I/AAAAAAAAACI/wb6MsJJy1HE/viewupdate1_thumb.jpg?imgmax=800" style="border: 0px none; display: inline;" title="viewupdate1" width="244" /&gt;&lt;/a&gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If the view is more complex, the query engine doesn’t know how to execute the operation and the update fails. There may be several different error messages, depending on the type of the error. For example, if you have calculated column in your view, you cant update this column and obviously you can’t insert rows into the view. The following view returns more or less the same information as the Person.vContact1, but it replaces original value of MiddleName column with custom string:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div class="csharpcode" id="codeSnippet"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;ALTER&lt;/span&gt; &lt;span class="kwrd"&gt;view&lt;/span&gt; [Person].[vContact2]&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span class="kwrd"&gt;as&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum3"&gt;   3:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; ContactID, NameStyle, &lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum4"&gt;   4:&lt;/span&gt; &lt;span class="kwrd"&gt;case&lt;/span&gt; &lt;span class="kwrd"&gt;when&lt;/span&gt; Title = &lt;span class="str"&gt;'Mr.'&lt;/span&gt; &lt;span class="kwrd"&gt;then&lt;/span&gt; &lt;span class="str"&gt;'Very long title 1'&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum5"&gt;   5:&lt;/span&gt;     &lt;span class="kwrd"&gt;when&lt;/span&gt; Title = &lt;span class="str"&gt;'Ms.'&lt;/span&gt; &lt;span class="kwrd"&gt;then&lt;/span&gt; &lt;span class="str"&gt;'Very long title 2'&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum6"&gt;   6:&lt;/span&gt;     &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="str"&gt;'Other title'&lt;/span&gt; &lt;span class="kwrd"&gt;end&lt;/span&gt; [&lt;span class="kwrd"&gt;Full&lt;/span&gt; Title], &lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum7"&gt;   7:&lt;/span&gt; FirstName, MiddleName, LastName, Suffix, EmailAddress, EmailPromotion, Phone, PasswordHash, PasswordSalt, rowguid, ModifiedDate&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum8"&gt;   8:&lt;/span&gt; &lt;span class="kwrd"&gt;from&lt;/span&gt; Person.Contact&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
If you try to update the Full Title column, the update will fail:&lt;br /&gt;
&lt;br /&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div class="csharpcode" id="codeSnippet"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; * &lt;span class="kwrd"&gt;from&lt;/span&gt; Person.vContact2 &lt;span class="kwrd"&gt;where&lt;/span&gt; ContactID = 1&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span class="kwrd"&gt;update&lt;/span&gt; Person.vContact1 &lt;span class="kwrd"&gt;set&lt;/span&gt; [&lt;span class="kwrd"&gt;Full&lt;/span&gt; Title] = &lt;span class="str"&gt;'Some other title'&lt;/span&gt; &lt;span class="kwrd"&gt;where&lt;/span&gt; ContactID = 1&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum3"&gt;   3:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; * &lt;span class="kwrd"&gt;from&lt;/span&gt; Person.vContact2 &lt;span class="kwrd"&gt;where&lt;/span&gt; ContactID = 1&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;span style="color: red; font-family: Courier New; font-size: x-small;"&gt;Msg 207, Level 16, State 1, Line 2&lt;br /&gt;    Invalid column name 'Full Title'.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is obviously reasonable: Full Title column is calculated at runtime, when the view is executed and cannot be altered in any way because there is no storage related with this column – this column doesn’t exist in the table. You can however update other columns in this view, because they are bound directly to columns in the table.&lt;br /&gt;
&lt;br /&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div class="csharpcode" id="codeSnippet"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; * &lt;span class="kwrd"&gt;from&lt;/span&gt; Person.vContact2 &lt;span class="kwrd"&gt;where&lt;/span&gt; ContactID = 1&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span class="kwrd"&gt;update&lt;/span&gt; Person.vContact1 &lt;span class="kwrd"&gt;set&lt;/span&gt; MiddleName = &lt;span class="str"&gt;'D.'&lt;/span&gt; &lt;span class="kwrd"&gt;where&lt;/span&gt; ContactID = 1&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum3"&gt;   3:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; * &lt;span class="kwrd"&gt;from&lt;/span&gt; Person.vContact2 &lt;span class="kwrd"&gt;where&lt;/span&gt; ContactID = 1&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
In some cases views return data from more than one table. Let’s examine such case. The following script updates City name in one of the tables that comprise the Purchasing.vVendor view:&lt;br /&gt;
&lt;br /&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div class="csharpcode" id="codeSnippet"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; * &lt;span class="kwrd"&gt;from&lt;/span&gt; Purchasing.vVendor &lt;span class="kwrd"&gt;where&lt;/span&gt; VendorId = 1&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; * &lt;span class="kwrd"&gt;from&lt;/span&gt; Person.Address &lt;span class="kwrd"&gt;where&lt;/span&gt; AddressLine1 = &lt;span class="str"&gt;'683 Larch Ct.'&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum3"&gt;   3:&lt;/span&gt; &lt;span class="kwrd"&gt;update&lt;/span&gt; Purchasing.vVendor &lt;span class="kwrd"&gt;set&lt;/span&gt; City = &lt;span class="str"&gt;'Buenos Aires'&lt;/span&gt; &lt;span class="kwrd"&gt;where&lt;/span&gt; VendorId = 1&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum4"&gt;   4:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; * &lt;span class="kwrd"&gt;from&lt;/span&gt; Person.Address &lt;span class="kwrd"&gt;where&lt;/span&gt; AddressLine1 = &lt;span class="str"&gt;'683 Larch Ct.'&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum5"&gt;   5:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; * &lt;span class="kwrd"&gt;from&lt;/span&gt; Purchasing.vVendor &lt;span class="kwrd"&gt;where&lt;/span&gt; VendorId = 1&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
When you run the above script you’ll notice that query engine was smart enough to update only appropriate row in the Person.Address table. Note also that the view,although joins eight tables, uses inner joins only and the query engine is able to determine exact range of rows to update in each participating table.&lt;br /&gt;
&lt;br /&gt;
There are some other conditions that have to be met to make a view updateable, for example, when you run an update query, you have to modify only columns from one base table at a time. The following query fails:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div class="csharpcode" id="codeSnippet"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;update&lt;/span&gt; Purchasing.vVendor &lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum2"&gt;   2:&lt;/span&gt;     &lt;span class="kwrd"&gt;set&lt;/span&gt; City = &lt;span class="str"&gt;'Buenos Aires'&lt;/span&gt;,&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum3"&gt;   3:&lt;/span&gt;     MiddleName = &lt;span class="str"&gt;'M.'&lt;/span&gt; &lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum4"&gt;   4:&lt;/span&gt;     &lt;span class="kwrd"&gt;where&lt;/span&gt; VendorId = 1&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;span style="color: red; font-family: Courier New; font-size: x-small;"&gt;Msg 4405, Level 16, State 1, Line 1&lt;br /&gt;    View or function 'Purchasing.vVendor' is not updatable because the modification affects multiple base tables.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Other conditions include (&lt;a href="http://msdn.microsoft.com/en-us/library/ms180800.aspx" target="_blank"&gt;after MSDN&lt;/a&gt;):&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;
The columns being modified in the view must directly reference the underlying data in the table columns. The columns cannot be derived in any other way, such as through the following:
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;
An aggregate function: AVG, COUNT, SUM, MIN, MAX, GROUPING, STDEV, STDEVP, VAR, and VARP.
&lt;/li&gt;
&lt;li&gt;
A computation. The column cannot be computed from an expression that uses other columns. Columns that are formed by using the set operators UNION, UNION ALL, CROSSJOIN, EXCEPT, and INTERSECT amount to a computation and are also not updatable.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
The columns being modified are not affected by GROUP BY, HAVING, or DISTINCT clauses.
&lt;/li&gt;
&lt;li&gt;
TOP is not used anywhere in the select_statement of the view together with the WITH CHECK OPTION clause.
&lt;/li&gt;
&lt;/ul&gt;
This will conclude first part of the series. In the next post I will write about triggers on views and their possible usage.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:e28585f0-805c-49d5-8eb4-83d2b3a1d5ef" style="display: inline; float: none; margin: 0px; padding: 0px;"&gt;
Technorati Tags: &lt;a href="http://technorati.com/tags/TSql" rel="tag"&gt;TSql&lt;/a&gt;,&lt;a href="http://technorati.com/tags/t-sql" rel="tag"&gt;t-sql&lt;/a&gt;,&lt;a href="http://technorati.com/tags/SQL+Server" rel="tag"&gt;SQL Server&lt;/a&gt;,&lt;a href="http://technorati.com/tags/CREATE+VIEW" rel="tag"&gt;CREATE VIEW&lt;/a&gt;,&lt;a href="http://technorati.com/tags/INSTEAD+OF" rel="tag"&gt;INSTEAD OF&lt;/a&gt;,&lt;a href="http://technorati.com/tags/AdventureWorks" rel="tag"&gt;AdventureWorks&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Execution+plan" rel="tag"&gt;Execution plan&lt;/a&gt;,&lt;a href="http://technorati.com/tags/code" rel="tag"&gt;code&lt;/a&gt;,&lt;a href="http://technorati.com/tags/programming" rel="tag"&gt;programming&lt;/a&gt;,&lt;a href="http://technorati.com/tags/DDL" rel="tag"&gt;DDL&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/902486075140485537-4113367191299684378?l=usepubs.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=wlf6M4FMEVY:goFcoG6jJf4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=wlf6M4FMEVY:goFcoG6jJf4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=wlf6M4FMEVY:goFcoG6jJf4:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=wlf6M4FMEVY:goFcoG6jJf4:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=wlf6M4FMEVY:goFcoG6jJf4:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=wlf6M4FMEVY:goFcoG6jJf4:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=wlf6M4FMEVY:goFcoG6jJf4:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=wlf6M4FMEVY:goFcoG6jJf4:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=wlf6M4FMEVY:goFcoG6jJf4:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=wlf6M4FMEVY:goFcoG6jJf4:3QFJfmc7Om4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=wlf6M4FMEVY:goFcoG6jJf4:3QFJfmc7Om4" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PiotrRodak/~4/wlf6M4FMEVY" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PiotrRodak/~3/wlf6M4FMEVY/updateable-views-how-to-use-them.html</link><author>noreply@blogger.com (Piotr Rodak)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/_ZwcS80etW1Q/TB_n2w5F57I/AAAAAAAAACI/wb6MsJJy1HE/s72-c/viewupdate1_thumb.jpg?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://usepubs.blogspot.com/2010/06/updateable-views-how-to-use-them.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-902486075140485537.post-5181886386910360444</guid><pubDate>Wed, 16 Jun 2010 19:53:00 +0000</pubDate><atom:updated>2010-06-18T00:13:33.811+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">SQL Server 2008</category><category domain="http://www.blogger.com/atom/ns#">CREATE TABLE</category><category domain="http://www.blogger.com/atom/ns#">tools</category><category domain="http://www.blogger.com/atom/ns#">Management Studio 2008</category><category domain="http://www.blogger.com/atom/ns#">tsql</category><category domain="http://www.blogger.com/atom/ns#">tips and tricks</category><category domain="http://www.blogger.com/atom/ns#">good practices</category><category domain="http://www.blogger.com/atom/ns#">DDL</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#">DROP TABLE</category><category domain="http://www.blogger.com/atom/ns#">code</category><category domain="http://www.blogger.com/atom/ns#">script</category><category domain="http://www.blogger.com/atom/ns#">things I like</category><title>Things I like – generate DROP .. CREATE scripts</title><description>I will be writing about things I like from time to time. That is SQL Server things - other than beer, good books and company. &lt;br /&gt;
For today, one small thing but how useful. In SQL Server Management Studio 2008 you can script objects as DROP and CREATE in one go:&lt;br /&gt;
&lt;a href="http://lh3.ggpht.com/_ZwcS80etW1Q/TBkrvtP7kRI/AAAAAAAAAB8/3AJa8w199mM/s1600-h/screenshot38%5B2%5D.jpg"&gt;&lt;img alt="screenshot38" border="0" height="146" src="http://lh4.ggpht.com/_ZwcS80etW1Q/TBkrwIAGY8I/AAAAAAAAACA/p7bvtBCqcKE/screenshot38_thumb.jpg?imgmax=800" style="border: 0px none; display: inline;" title="screenshot38" width="244" /&gt;&lt;/a&gt; &lt;br /&gt;
This is very useful for us, as we store all database objects in our SVN as DROP..CREATE scripts. Using this feature saves quite a bit of time each time we want to update the source control.&lt;br /&gt;
I noticed an interesting behavior - if you script your table this way, all constraints defined in the table are scripted with drop statements before the actual DROP TABLE statement is included. This is quite handy as you can easily modify this script to change constraint names or definitions without having to script them separately.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:99a1bec7-5f87-4d2e-9083-8e81d80d045e" style="display: inline; float: none; margin: 0px; padding: 0px;"&gt;
Technorati Tags: &lt;a href="http://technorati.com/tags/SQL+Server" rel="tag"&gt;SQL Server&lt;/a&gt;,&lt;a href="http://technorati.com/tags/tsql" rel="tag"&gt;tsql&lt;/a&gt;,&lt;a href="http://technorati.com/tags/t-sql" rel="tag"&gt;t-sql&lt;/a&gt;,&lt;a href="http://technorati.com/tags/code" rel="tag"&gt;code&lt;/a&gt;,&lt;a href="http://technorati.com/tags/tips+and+tricks" rel="tag"&gt;tips and tricks&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/902486075140485537-5181886386910360444?l=usepubs.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=DC67K2n_tyE:4MwcELqa-2k:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=DC67K2n_tyE:4MwcELqa-2k:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=DC67K2n_tyE:4MwcELqa-2k:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=DC67K2n_tyE:4MwcELqa-2k:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=DC67K2n_tyE:4MwcELqa-2k:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=DC67K2n_tyE:4MwcELqa-2k:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=DC67K2n_tyE:4MwcELqa-2k:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=DC67K2n_tyE:4MwcELqa-2k:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=DC67K2n_tyE:4MwcELqa-2k:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=DC67K2n_tyE:4MwcELqa-2k:3QFJfmc7Om4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=DC67K2n_tyE:4MwcELqa-2k:3QFJfmc7Om4" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PiotrRodak/~4/DC67K2n_tyE" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PiotrRodak/~3/DC67K2n_tyE/things-i-like-generate-drop-create.html</link><author>noreply@blogger.com (Piotr Rodak)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/_ZwcS80etW1Q/TBkrwIAGY8I/AAAAAAAAACA/p7bvtBCqcKE/s72-c/screenshot38_thumb.jpg?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://usepubs.blogspot.com/2010/06/things-i-like-generate-drop-create.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-902486075140485537.post-4419824845981775947</guid><pubDate>Sun, 13 Jun 2010 22:59:00 +0000</pubDate><atom:updated>2010-06-22T22:47:54.440+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">t-sql</category><category domain="http://www.blogger.com/atom/ns#">naming convention</category><category domain="http://www.blogger.com/atom/ns#">ALTER TABLE</category><category domain="http://www.blogger.com/atom/ns#">tsql</category><category domain="http://www.blogger.com/atom/ns#">tips and tricks</category><category domain="http://www.blogger.com/atom/ns#">SQLServerPedia Syndication</category><category domain="http://www.blogger.com/atom/ns#">constraints</category><category domain="http://www.blogger.com/atom/ns#">code</category><category domain="http://www.blogger.com/atom/ns#">programming</category><category domain="http://www.blogger.com/atom/ns#">good practices</category><category domain="http://www.blogger.com/atom/ns#">refactoring</category><category domain="http://www.blogger.com/atom/ns#">script</category><title>Coding practices - Call your constraints</title><description>I wrote a few weeks ago about &lt;a href="http://sqlblogcasts.com/blogs/piotr_rodak/archive/2010/05/24/good-practices-database-programming-unit-testing.aspx"&gt;unit tests and good practice of naming your constraints&lt;/a&gt;. I think that most of the developers are used to call primary keys and unique constraints, sometimes foreign keys. But in most of the code I’ve seen the &lt;b&gt;CHECK&lt;/b&gt; and &lt;b&gt;DEFAULT&lt;/b&gt; constraints remain unnamed.

You might wonder, why bother? The answer is that as long as you don’t have to drop the constraints, everything is OK – apart from cryptic error messages if the constraints are violated. The problem begins if for some reason you need to drop the constraint – for example to change range of the allowed values or default value of a column. The other scenario is also painful – if you want to compare two databases and you script out objects with constraint names. If you let SQL Server to name your constraints, each database you create from your scripts is &lt;b&gt;different&lt;/b&gt;. And you have different error messages in production than in UAT for example. Not a very good idea for troubleshooting.

Let’s suppose you create a table for storing order summaries.
&lt;br /&gt;
&lt;div class="csharpcode-wrapper" id="codeSnippetWrapper"&gt;
&lt;div class="csharpcode" id="codeSnippet"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;create&lt;/span&gt; &lt;span class="kwrd"&gt;table&lt;/span&gt; OrderSummary&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum2"&gt;   2:&lt;/span&gt; (&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum3"&gt;   3:&lt;/span&gt; OrderID &lt;span class="kwrd"&gt;int&lt;/span&gt; &lt;span class="kwrd"&gt;not&lt;/span&gt; &lt;span class="kwrd"&gt;null&lt;/span&gt;,&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum4"&gt;   4:&lt;/span&gt; OrderValue &lt;span class="kwrd"&gt;decimal&lt;/span&gt;(10,2) &lt;span class="kwrd"&gt;not&lt;/span&gt; &lt;span class="kwrd"&gt;null&lt;/span&gt;,&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum5"&gt;   5:&lt;/span&gt; OrderCurrency &lt;span class="kwrd"&gt;char&lt;/span&gt;(3) &lt;span class="kwrd"&gt;check&lt;/span&gt; (OrderCurrency &lt;span class="kwrd"&gt;in&lt;/span&gt; (&lt;span class="str"&gt;'EUR'&lt;/span&gt;, &lt;span class="str"&gt;'USD'&lt;/span&gt;)),&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum6"&gt;   6:&lt;/span&gt; OrderDate datetime &lt;span class="kwrd"&gt;not&lt;/span&gt; &lt;span class="kwrd"&gt;null&lt;/span&gt; &lt;span class="kwrd"&gt;default&lt;/span&gt; getdate()&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum7"&gt;   7:&lt;/span&gt; )&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
Looks nice. But to drop the constraint on the OrderCurrency column, you have to use dynamic sql:
&lt;br /&gt;
&lt;div class="csharpcode-wrapper" id="codeSnippetWrapper"&gt;
&lt;div class="csharpcode" id="codeSnippet"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; * &lt;span class="kwrd"&gt;from&lt;/span&gt; sys.check_constraints&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span class="kwrd"&gt;declare&lt;/span&gt; @&lt;span class="kwrd"&gt;sql&lt;/span&gt; nvarchar(200)&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum3"&gt;   3:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; @&lt;span class="kwrd"&gt;sql&lt;/span&gt; = N&lt;span class="str"&gt;'alter table OrderSummary drop constraint '&lt;/span&gt; + &lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum4"&gt;   4:&lt;/span&gt;         quotename((&lt;span class="kwrd"&gt;select&lt;/span&gt; name &lt;span class="kwrd"&gt;from&lt;/span&gt; sys.check_constraints &lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum5"&gt;   5:&lt;/span&gt;             &lt;span class="kwrd"&gt;where&lt;/span&gt; parent_object_id = object_id(&lt;span class="str"&gt;'OrderSummary'&lt;/span&gt;)))&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum6"&gt;   6:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum7"&gt;   7:&lt;/span&gt; --&lt;span class="kwrd"&gt;print&lt;/span&gt; @&lt;span class="kwrd"&gt;sql&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum8"&gt;   8:&lt;/span&gt; &lt;span class="kwrd"&gt;exec&lt;/span&gt; sp_executesql @sql&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
Please note that the above script works only if you have one unnamed check constraint. If you have more constraints, you have to write more complex code. Not a very nice option if you want to have some control on which constraints you want to drop and which are to stay.
Now if you run the following script, you will see that each time you create the table, names of constraints are different:
&lt;br /&gt;
&lt;div class="csharpcode-wrapper" id="codeSnippetWrapper"&gt;
&lt;div class="csharpcode" id="codeSnippet"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;use&lt;/span&gt; master&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt; &lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum3"&gt;   3:&lt;/span&gt; &lt;span class="kwrd"&gt;create&lt;/span&gt; &lt;span class="kwrd"&gt;database&lt;/span&gt; devDB&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum4"&gt;   4:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum5"&gt;   5:&lt;/span&gt; &lt;span class="kwrd"&gt;use&lt;/span&gt; devDB&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum6"&gt;   6:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum7"&gt;   7:&lt;/span&gt; --simulate various test objects creating &lt;span class="kwrd"&gt;and&lt;/span&gt; dropping &lt;span class="kwrd"&gt;in&lt;/span&gt; DEV &lt;span class="kwrd"&gt;database&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum8"&gt;   8:&lt;/span&gt; &lt;span class="kwrd"&gt;create&lt;/span&gt; &lt;span class="kwrd"&gt;table&lt;/span&gt; OrderSummaryTest&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum9"&gt;   9:&lt;/span&gt; (&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum10"&gt;  10:&lt;/span&gt; OrderID &lt;span class="kwrd"&gt;int&lt;/span&gt; &lt;span class="kwrd"&gt;not&lt;/span&gt; &lt;span class="kwrd"&gt;null&lt;/span&gt;,&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum11"&gt;  11:&lt;/span&gt; OrderCurrency &lt;span class="kwrd"&gt;char&lt;/span&gt;(3) &lt;span class="kwrd"&gt;check&lt;/span&gt; (OrderCurrency &lt;span class="kwrd"&gt;in&lt;/span&gt; (&lt;span class="str"&gt;'EUR'&lt;/span&gt;, &lt;span class="str"&gt;'USD'&lt;/span&gt;)),&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum12"&gt;  12:&lt;/span&gt; OrderDate datetime &lt;span class="kwrd"&gt;not&lt;/span&gt; &lt;span class="kwrd"&gt;null&lt;/span&gt; &lt;span class="kwrd"&gt;default&lt;/span&gt; getdate()&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum13"&gt;  13:&lt;/span&gt; )&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum14"&gt;  14:&lt;/span&gt; &lt;span class="kwrd"&gt;drop&lt;/span&gt; &lt;span class="kwrd"&gt;table&lt;/span&gt; OrderSummaryTest&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum15"&gt;  15:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum16"&gt;  16:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum17"&gt;  17:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum18"&gt;  18:&lt;/span&gt; &lt;span class="kwrd"&gt;create&lt;/span&gt; &lt;span class="kwrd"&gt;table&lt;/span&gt; OrderSummary&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum19"&gt;  19:&lt;/span&gt; (&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum20"&gt;  20:&lt;/span&gt; OrderID &lt;span class="kwrd"&gt;int&lt;/span&gt; &lt;span class="kwrd"&gt;not&lt;/span&gt; &lt;span class="kwrd"&gt;null&lt;/span&gt;,&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum21"&gt;  21:&lt;/span&gt; OrderValue &lt;span class="kwrd"&gt;decimal&lt;/span&gt;(10,2) &lt;span class="kwrd"&gt;not&lt;/span&gt; &lt;span class="kwrd"&gt;null&lt;/span&gt;,&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum22"&gt;  22:&lt;/span&gt; OrderCurrency &lt;span class="kwrd"&gt;char&lt;/span&gt;(3) &lt;span class="kwrd"&gt;check&lt;/span&gt; (OrderCurrency &lt;span class="kwrd"&gt;in&lt;/span&gt; (&lt;span class="str"&gt;'EUR'&lt;/span&gt;, &lt;span class="str"&gt;'USD'&lt;/span&gt;)),&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum23"&gt;  23:&lt;/span&gt; OrderDate datetime &lt;span class="kwrd"&gt;not&lt;/span&gt; &lt;span class="kwrd"&gt;null&lt;/span&gt; &lt;span class="kwrd"&gt;default&lt;/span&gt; getdate()&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum24"&gt;  24:&lt;/span&gt; )&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum25"&gt;  25:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum26"&gt;  26:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum27"&gt;  27:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; &lt;span class="kwrd"&gt;convert&lt;/span&gt;(&lt;span class="kwrd"&gt;varchar&lt;/span&gt;(10), db_name()) [test], &lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum28"&gt;  28:&lt;/span&gt;     name &lt;span class="kwrd"&gt;from&lt;/span&gt; sys.check_constraints &lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum29"&gt;  29:&lt;/span&gt;     &lt;span class="kwrd"&gt;where&lt;/span&gt; parent_object_id = object_id(&lt;span class="str"&gt;'OrderSummary'&lt;/span&gt;)&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum30"&gt;  30:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum31"&gt;  31:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum32"&gt;  32:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum33"&gt;  33:&lt;/span&gt; &lt;span class="kwrd"&gt;create&lt;/span&gt; &lt;span class="kwrd"&gt;database&lt;/span&gt; prodDB&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum34"&gt;  34:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum35"&gt;  35:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum36"&gt;  36:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum37"&gt;  37:&lt;/span&gt; &lt;span class="kwrd"&gt;use&lt;/span&gt; prodDB&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum38"&gt;  38:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum39"&gt;  39:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum40"&gt;  40:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum41"&gt;  41:&lt;/span&gt; &lt;span class="kwrd"&gt;create&lt;/span&gt; &lt;span class="kwrd"&gt;table&lt;/span&gt; OrderSummary&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum42"&gt;  42:&lt;/span&gt; (&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum43"&gt;  43:&lt;/span&gt; OrderID &lt;span class="kwrd"&gt;int&lt;/span&gt; &lt;span class="kwrd"&gt;not&lt;/span&gt; &lt;span class="kwrd"&gt;null&lt;/span&gt;,&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum44"&gt;  44:&lt;/span&gt; OrderValue &lt;span class="kwrd"&gt;decimal&lt;/span&gt;(10,2) &lt;span class="kwrd"&gt;not&lt;/span&gt; &lt;span class="kwrd"&gt;null&lt;/span&gt;,&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum45"&gt;  45:&lt;/span&gt; OrderCurrency &lt;span class="kwrd"&gt;char&lt;/span&gt;(3) &lt;span class="kwrd"&gt;check&lt;/span&gt; (OrderCurrency &lt;span class="kwrd"&gt;in&lt;/span&gt; (&lt;span class="str"&gt;'EUR'&lt;/span&gt;, &lt;span class="str"&gt;'USD'&lt;/span&gt;)),&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum46"&gt;  46:&lt;/span&gt; OrderDate datetime &lt;span class="kwrd"&gt;not&lt;/span&gt; &lt;span class="kwrd"&gt;null&lt;/span&gt; &lt;span class="kwrd"&gt;default&lt;/span&gt; getdate()&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum47"&gt;  47:&lt;/span&gt; )&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum48"&gt;  48:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum49"&gt;  49:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum50"&gt;  50:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum51"&gt;  51:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; &lt;span class="kwrd"&gt;convert&lt;/span&gt;(&lt;span class="kwrd"&gt;varchar&lt;/span&gt;(10), db_name()) [test], &lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum52"&gt;  52:&lt;/span&gt;     name &lt;span class="kwrd"&gt;from&lt;/span&gt; sys.check_constraints &lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum53"&gt;  53:&lt;/span&gt;     &lt;span class="kwrd"&gt;where&lt;/span&gt; parent_object_id = object_id(&lt;span class="str"&gt;'OrderSummary'&lt;/span&gt;)&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum54"&gt;  54:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum55"&gt;  55:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum56"&gt;  56:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum57"&gt;  57:&lt;/span&gt; ----cleanup&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum58"&gt;  58:&lt;/span&gt; &lt;span class="kwrd"&gt;use&lt;/span&gt; master&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum59"&gt;  59:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum60"&gt;  60:&lt;/span&gt; &lt;span class="kwrd"&gt;drop&lt;/span&gt; &lt;span class="kwrd"&gt;database&lt;/span&gt; devDB&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum61"&gt;  61:&lt;/span&gt; &lt;span class="kwrd"&gt;drop&lt;/span&gt; &lt;span class="kwrd"&gt;database&lt;/span&gt; prodDB&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum62"&gt;  62:&lt;/span&gt; go&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
As you see, the constraint names are different and &lt;b&gt;UGLY&lt;/b&gt;. Note that I simulated object creation and destruction in devDB, because if you comment lines 7 – 14, you may get the same object ids for the constraints. But this never happens in real life.
If you want to avoid such problems and make your and your dba’s life easier, give your constraints names, like in the following script:
&lt;br /&gt;
&lt;div class="csharpcode-wrapper" id="codeSnippetWrapper"&gt;
&lt;div class="csharpcode" id="codeSnippet"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;create&lt;/span&gt; &lt;span class="kwrd"&gt;table&lt;/span&gt; OrderSummary&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum2"&gt;   2:&lt;/span&gt; (&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum3"&gt;   3:&lt;/span&gt; OrderID &lt;span class="kwrd"&gt;int&lt;/span&gt; &lt;span class="kwrd"&gt;not&lt;/span&gt; &lt;span class="kwrd"&gt;null&lt;/span&gt;,&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum4"&gt;   4:&lt;/span&gt; OrderValue &lt;span class="kwrd"&gt;decimal&lt;/span&gt;(10,2) &lt;span class="kwrd"&gt;not&lt;/span&gt; &lt;span class="kwrd"&gt;null&lt;/span&gt;,&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum5"&gt;   5:&lt;/span&gt; OrderCurrency &lt;span class="kwrd"&gt;char&lt;/span&gt;(3) &lt;span class="kwrd"&gt;constraint&lt;/span&gt; CHK_OrderCurrencyRange &lt;span class="kwrd"&gt;check&lt;/span&gt; (OrderCurrency &lt;span class="kwrd"&gt;in&lt;/span&gt; (&lt;span class="str"&gt;'EUR'&lt;/span&gt;, &lt;span class="str"&gt;'USD'&lt;/span&gt;)),&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum6"&gt;   6:&lt;/span&gt; OrderDate datetime &lt;span class="kwrd"&gt;not&lt;/span&gt; &lt;span class="kwrd"&gt;null&lt;/span&gt; &lt;span class="kwrd"&gt;constraint&lt;/span&gt; DF_OrderDate &lt;span class="kwrd"&gt;default&lt;/span&gt; getdate()&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum7"&gt;   7:&lt;/span&gt; )&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
This way, to drop the default constraint you just have to call:
&lt;br /&gt;
&lt;div class="csharpcode-wrapper" id="codeSnippetWrapper"&gt;
&lt;div class="csharpcode" id="codeSnippet"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;alter&lt;/span&gt; &lt;span class="kwrd"&gt;table&lt;/span&gt; OrderSummary &lt;span class="kwrd"&gt;drop&lt;/span&gt; &lt;span class="kwrd"&gt;constraint&lt;/span&gt; [DF_OrderDate]&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
No dynamic SQL required, and code is 100% same in production and in DEV. 
To sum it up, if you get the habit of assigning names to ALL your constraints, your code will look better and others will be able to understand it faster, what is important when troubleshooting production issues.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:83ae01d0-caee-4052-9067-23ccd0043e9c" style="display: inline; float: none; margin: 0px; padding: 0px;"&gt;
Technorati Tags: &lt;a href="http://technorati.com/tags/tsql" rel="tag"&gt;tsql&lt;/a&gt;,&lt;a href="http://technorati.com/tags/SQL+Server" rel="tag"&gt;SQL Server&lt;/a&gt;,&lt;a href="http://technorati.com/tags/t-sql" rel="tag"&gt;t-sql&lt;/a&gt;,&lt;a href="http://technorati.com/tags/programming" rel="tag"&gt;programming&lt;/a&gt;,&lt;a href="http://technorati.com/tags/script" rel="tag"&gt;script&lt;/a&gt;,&lt;a href="http://technorati.com/tags/tips+and+tricks" rel="tag"&gt;tips and tricks&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/902486075140485537-4419824845981775947?l=usepubs.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=8DONriiOgcs:VH-U7ZWTrno:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=8DONriiOgcs:VH-U7ZWTrno:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=8DONriiOgcs:VH-U7ZWTrno:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=8DONriiOgcs:VH-U7ZWTrno:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=8DONriiOgcs:VH-U7ZWTrno:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=8DONriiOgcs:VH-U7ZWTrno:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=8DONriiOgcs:VH-U7ZWTrno:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=8DONriiOgcs:VH-U7ZWTrno:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=8DONriiOgcs:VH-U7ZWTrno:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=8DONriiOgcs:VH-U7ZWTrno:3QFJfmc7Om4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=8DONriiOgcs:VH-U7ZWTrno:3QFJfmc7Om4" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PiotrRodak/~4/8DONriiOgcs" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PiotrRodak/~3/8DONriiOgcs/coding-practices-call-your-constraints.html</link><author>noreply@blogger.com (Piotr Rodak)</author><thr:total>4</thr:total><feedburner:origLink>http://usepubs.blogspot.com/2010/06/coding-practices-call-your-constraints.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-902486075140485537.post-5521034858502458662</guid><pubDate>Thu, 10 Jun 2010 00:04:00 +0000</pubDate><atom:updated>2010-06-10T01:53:24.131+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">t-sql</category><category domain="http://www.blogger.com/atom/ns#">tips and tricks</category><category domain="http://www.blogger.com/atom/ns#">code</category><category domain="http://www.blogger.com/atom/ns#">programming</category><category domain="http://www.blogger.com/atom/ns#">good practices</category><category domain="http://www.blogger.com/atom/ns#">script</category><title>sp_addrolemember – implicit create user with problems</title><description>This post was to be about an interesting issue I encountered a few days ago. I will write about this issue in the future, but I tried to reproduce it on my home laptop and while doing so, I came across behaviour I wasn’t aware of.&lt;br /&gt;
As you may know, &lt;a href="http://usepubs.blogspot.com/2010/06/save-time-use-roles.html" target="_blank"&gt;using application roles&lt;/a&gt; simplifies your life. To add an user to application role you use &lt;a href="http://msdn.microsoft.com/en-us/library/ms187750.aspx" target="_blank"&gt;sp_addrolemember&lt;/a&gt; procedure. Working on the script to reproduce my permissions issue, I created user in database and assigned it to custom role. When you create user explicitly, the default schema of the user will be &lt;b&gt;dbo&lt;/b&gt;.&lt;br /&gt;
&lt;div class="csharpcode-wrapper" id="codeSnippetWrapper"&gt;
&lt;div class="csharpcode" id="codeSnippet"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;use&lt;/span&gt; master&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum3"&gt;   3:&lt;/span&gt; &lt;span class="kwrd"&gt;create&lt;/span&gt; &lt;span class="kwrd"&gt;database&lt;/span&gt; TestSchemaDb&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum4"&gt;   4:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum5"&gt;   5:&lt;/span&gt; &lt;span class="kwrd"&gt;create&lt;/span&gt; login frank &lt;span class="kwrd"&gt;with&lt;/span&gt; password=&lt;span class="str"&gt;'StrongestPassword'&lt;/span&gt;, check_policy=&lt;span class="kwrd"&gt;off&lt;/span&gt;, check_expiration=&lt;span class="kwrd"&gt;off&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum6"&gt;   6:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum7"&gt;   7:&lt;/span&gt; &lt;span class="kwrd"&gt;use&lt;/span&gt; TestSchemaDb&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum8"&gt;   8:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum9"&gt;   9:&lt;/span&gt; &lt;span class="kwrd"&gt;create&lt;/span&gt; &lt;span class="kwrd"&gt;role&lt;/span&gt; WrapRole&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum10"&gt;  10:&lt;/span&gt; &lt;span class="kwrd"&gt;exec&lt;/span&gt; sp_addrolemember &lt;span class="str"&gt;'db_ddladmin'&lt;/span&gt;, &lt;span class="str"&gt;'WrapRole'&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum11"&gt;  11:&lt;/span&gt; &lt;span class="kwrd"&gt;exec&lt;/span&gt; sp_addrolemember &lt;span class="str"&gt;'db_datawriter'&lt;/span&gt;, &lt;span class="str"&gt;'WrapRole'&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum12"&gt;  12:&lt;/span&gt; &lt;span class="kwrd"&gt;exec&lt;/span&gt; sp_addrolemember &lt;span class="str"&gt;'db_datareader'&lt;/span&gt;, &lt;span class="str"&gt;'WrapRole'&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum13"&gt;  13:&lt;/span&gt; &lt;span class="kwrd"&gt;grant&lt;/span&gt; &lt;span class="kwrd"&gt;execute&lt;/span&gt; &lt;span class="kwrd"&gt;to&lt;/span&gt; WrapRole&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum14"&gt;  14:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum15"&gt;  15:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum16"&gt;  16:&lt;/span&gt; ---&lt;span class="kwrd"&gt;create&lt;/span&gt; &lt;span class="kwrd"&gt;user&lt;/span&gt; &lt;span class="kwrd"&gt;and&lt;/span&gt; &lt;span class="kwrd"&gt;add&lt;/span&gt; him &lt;span class="kwrd"&gt;to&lt;/span&gt; the &lt;span class="kwrd"&gt;role&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum17"&gt;  17:&lt;/span&gt; &lt;span class="kwrd"&gt;create&lt;/span&gt; &lt;span class="kwrd"&gt;user&lt;/span&gt; frank &lt;span class="kwrd"&gt;from&lt;/span&gt; login frank&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum18"&gt;  18:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum19"&gt;  19:&lt;/span&gt; &lt;span class="kwrd"&gt;exec&lt;/span&gt; sp_addrolemember &lt;span class="str"&gt;'WrapRole'&lt;/span&gt;, &lt;span class="str"&gt;'frank'&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum20"&gt;  20:&lt;/span&gt; go&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
You can verify this with the following script:&lt;br /&gt;
&lt;div class="csharpcode-wrapper" id="codeSnippetWrapper"&gt;
&lt;div class="csharpcode" id="codeSnippet"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum1"&gt;   1:&lt;/span&gt; ---&lt;span class="kwrd"&gt;create&lt;/span&gt; &lt;span class="kwrd"&gt;schema&lt;/span&gt;, frank&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span class="kwrd"&gt;execute&lt;/span&gt; &lt;span class="kwrd"&gt;as&lt;/span&gt; &lt;span class="kwrd"&gt;user&lt;/span&gt;=&lt;span class="str"&gt;'frank'&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum3"&gt;   3:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; user_name() &lt;span class="kwrd"&gt;as&lt;/span&gt; [I am]&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum4"&gt;   4:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum5"&gt;   5:&lt;/span&gt; ---&lt;span class="kwrd"&gt;create&lt;/span&gt; &lt;span class="kwrd"&gt;table&lt;/span&gt;, frank&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum6"&gt;   6:&lt;/span&gt; &lt;span class="kwrd"&gt;create&lt;/span&gt; &lt;span class="kwrd"&gt;table&lt;/span&gt; tTable (a &lt;span class="kwrd"&gt;int&lt;/span&gt;, b &lt;span class="kwrd"&gt;int&lt;/span&gt;)&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum7"&gt;   7:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum8"&gt;   8:&lt;/span&gt; insert tTable(a, b) &lt;span class="kwrd"&gt;values&lt;/span&gt;(1, 2)&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum9"&gt;   9:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; * &lt;span class="kwrd"&gt;from&lt;/span&gt; tTable&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum10"&gt;  10:&lt;/span&gt; ---but, &lt;span class="kwrd"&gt;where&lt;/span&gt; &lt;span class="kwrd"&gt;is&lt;/span&gt; the &lt;span class="kwrd"&gt;table&lt;/span&gt;?&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum11"&gt;  11:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; object_schema_name(object_id(&lt;span class="str"&gt;'tTable'&lt;/span&gt;)) &lt;span class="kwrd"&gt;as&lt;/span&gt; [&lt;span class="kwrd"&gt;Table&lt;/span&gt; &lt;span class="kwrd"&gt;in&lt;/span&gt; this &lt;span class="kwrd"&gt;schema&lt;/span&gt;]&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum12"&gt;  12:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum13"&gt;  13:&lt;/span&gt; revert&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum14"&gt;  14:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; user_name() &lt;span class="kwrd"&gt;as&lt;/span&gt; [I am]&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum15"&gt;  15:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

The select statement in line 11 will return &lt;b&gt;dbo&lt;/b&gt; schema name.&lt;br /&gt;
&lt;br /&gt;
I noticed that when you don’t create an user but instead call sp_addrolemember, the user will be created in database. I thought that this was always true until yesterday, when I found out that this is the case only if you have a Windows login and create an user with the same name as the login. So for user frank, if we drop him from the database and try to create him using sp_addrolemember, we’ll receive an error:&lt;br /&gt;
&lt;div class="csharpcode-wrapper" id="codeSnippetWrapper"&gt;
&lt;div class="csharpcode" id="codeSnippet"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum1"&gt;   1:&lt;/span&gt; ---now &lt;span class="kwrd"&gt;second&lt;/span&gt; scenario&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span class="kwrd"&gt;drop&lt;/span&gt; &lt;span class="kwrd"&gt;user&lt;/span&gt; frank&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum3"&gt;   3:&lt;/span&gt; &lt;span class="kwrd"&gt;drop&lt;/span&gt; &lt;span class="kwrd"&gt;table&lt;/span&gt; tTable&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum4"&gt;   4:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum5"&gt;   5:&lt;/span&gt; --nothing returned&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum6"&gt;   6:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; * &lt;span class="kwrd"&gt;from&lt;/span&gt; sys.database_principals &lt;span class="kwrd"&gt;where&lt;/span&gt; name=&lt;span class="str"&gt;'frank'&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum7"&gt;   7:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum8"&gt;   8:&lt;/span&gt; --this fails, frank doesn&lt;span class="str"&gt;'t exist in the database&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum9"&gt;   9:&lt;/span&gt; exec sp_addrolemember 'WrapRole&lt;span class="str"&gt;', '&lt;/span&gt;frank'&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;span style="color: red; font-family: Courier New; font-size: x-small;"&gt;Msg 15410, Level 11, State 1, Procedure sp_addrolemember, Line 75 &lt;br/&gt;User or role 'frank' does not exist in this database.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
For user that we add from a Windows login, everything works, at a first glance:&lt;br /&gt;
&lt;div class="csharpcode-wrapper" id="codeSnippetWrapper"&gt;
&lt;div class="csharpcode" id="codeSnippet"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum1"&gt;   1:&lt;/span&gt; ---third scenario&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span class="kwrd"&gt;create&lt;/span&gt; login [Amilo\Ola] &lt;span class="kwrd"&gt;from&lt;/span&gt; windows&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum3"&gt;   3:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum4"&gt;   4:&lt;/span&gt; --don&lt;span class="str"&gt;'t create user in database&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum5"&gt;   5:&lt;/span&gt; go&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum6"&gt;   6:&lt;/span&gt; -- call sp_addrolemember&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum7"&gt;   7:&lt;/span&gt; exec sp_addrolemember 'WrapRole&lt;span class="str"&gt;', '&lt;/span&gt;Amilo\Ola'&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum8"&gt;   8:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
I tried to connect as this user:&lt;br /&gt;
&lt;div class="csharpcode-wrapper" id="codeSnippetWrapper"&gt;
&lt;div class="csharpcode" id="codeSnippet"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum1"&gt;   1:&lt;/span&gt; ---&lt;span class="kwrd"&gt;create&lt;/span&gt; &lt;span class="kwrd"&gt;schema&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span class="kwrd"&gt;execute&lt;/span&gt; &lt;span class="kwrd"&gt;as&lt;/span&gt; &lt;span class="kwrd"&gt;user&lt;/span&gt;=&lt;span class="str"&gt;'Amilo\Ola'&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum3"&gt;   3:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; user_name() &lt;span class="kwrd"&gt;as&lt;/span&gt; [I am]&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum4"&gt;   4:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
And I got error message:&lt;br /&gt;
&lt;span style="color: red; font-family: Courier New; font-size: x-small;"&gt;Msg 916, Level 14, State 1, Line 3 &lt;br/&gt;The server principal "Amilo\Ola" is not able to access the database "TestSchemaDb" under the current security context.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Ok, so I granted the connect right to the user:&lt;br /&gt;
&lt;div class="csharpcode-wrapper" id="codeSnippetWrapper"&gt;
&lt;div class="csharpcode" id="codeSnippet"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;grant&lt;/span&gt; &lt;span class="kwrd"&gt;connect&lt;/span&gt; &lt;span class="kwrd"&gt;to&lt;/span&gt; [Amilo\Ola]&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
The MSDN Help says that “if the new member is a Windows-level principal without corresponding user, new user is created, but may not be fully mapped to the login”. I wish I knew what “not fully mapped” means, besides that the user is created, but it doesn’t have the CONNECT right.&lt;br /&gt;
Now I was able to run the following script:&lt;br /&gt;
&lt;div class="csharpcode-wrapper" id="codeSnippetWrapper"&gt;
&lt;div class="csharpcode" id="codeSnippet"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum1"&gt;   1:&lt;/span&gt; ---&lt;span class="kwrd"&gt;create&lt;/span&gt; &lt;span class="kwrd"&gt;schema&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span class="kwrd"&gt;execute&lt;/span&gt; &lt;span class="kwrd"&gt;as&lt;/span&gt; &lt;span class="kwrd"&gt;user&lt;/span&gt;=&lt;span class="str"&gt;'Amilo\Ola'&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum3"&gt;   3:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; user_name() &lt;span class="kwrd"&gt;as&lt;/span&gt; [I am]&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum4"&gt;   4:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum5"&gt;   5:&lt;/span&gt; ---&lt;span class="kwrd"&gt;create&lt;/span&gt; &lt;span class="kwrd"&gt;table&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum6"&gt;   6:&lt;/span&gt; &lt;span class="kwrd"&gt;create&lt;/span&gt; &lt;span class="kwrd"&gt;table&lt;/span&gt; tTable (a &lt;span class="kwrd"&gt;int&lt;/span&gt;, b &lt;span class="kwrd"&gt;int&lt;/span&gt;)&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum7"&gt;   7:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum8"&gt;   8:&lt;/span&gt; insert tTable(a, b) &lt;span class="kwrd"&gt;values&lt;/span&gt;(1, 2)&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum9"&gt;   9:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; * &lt;span class="kwrd"&gt;from&lt;/span&gt; tTable&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum10"&gt;  10:&lt;/span&gt; ---but, &lt;span class="kwrd"&gt;where&lt;/span&gt; &lt;span class="kwrd"&gt;is&lt;/span&gt; the &lt;span class="kwrd"&gt;table&lt;/span&gt;?&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum11"&gt;  11:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; object_schema_name(object_id(&lt;span class="str"&gt;'tTable'&lt;/span&gt;)) &lt;span class="kwrd"&gt;as&lt;/span&gt; [&lt;span class="kwrd"&gt;Table&lt;/span&gt; &lt;span class="kwrd"&gt;in&lt;/span&gt; this &lt;span class="kwrd"&gt;schema&lt;/span&gt;]&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum12"&gt;  12:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum13"&gt;  13:&lt;/span&gt; revert&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum14"&gt;  14:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; user_name() &lt;span class="kwrd"&gt;as&lt;/span&gt; [I am]&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum15"&gt;  15:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
If you run it, you will notice that the result of the query in line 11 will return Amilo\Ola equivalent for login you use for testing. The table will be, if you don't explicitly specify schema, located in default schema of the user. So, if you happen to create user with sp_addrolemember, the objects the user creates may not be in expected place. This may lead to additional lookups performed by db engine for queries which don’t explicitly specify schemas and possibly to access exceptions if for example procedure created by one user accesses table created by another.&lt;br /&gt;
There is another caveat of this behavior: If you try to drop user who owns a schema, you will get an exception: &lt;br /&gt;
&lt;div class="csharpcode-wrapper" id="codeSnippetWrapper"&gt;
&lt;div class="csharpcode" id="codeSnippet"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;drop&lt;/span&gt; &lt;span class="kwrd"&gt;user&lt;/span&gt; [Amilo\Ola]&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum2"&gt;   2:&lt;/span&gt; go&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;span style="color: red; font-family: Courier New; font-size: x-small;"&gt;Msg 15138, Level 16, State 1, Line 2 &lt;br/&gt;The database principal owns a schema in the database, and cannot be dropped.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
You have to drop the schema first, and to do this, you have to transfer all objects in the schema to other location:&lt;br /&gt;
&lt;div class="csharpcode-wrapper" id="codeSnippetWrapper"&gt;
&lt;div class="csharpcode" id="codeSnippet"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;drop&lt;/span&gt; &lt;span class="kwrd"&gt;schema&lt;/span&gt; [Amilo\Ola]&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;span style="color: red; font-family: Courier New; font-size: x-small;"&gt;Msg 3729, Level 16, State 1, Line 2 &lt;br/&gt;Cannot drop schema 'Amilo\Ola' because it is being referenced by object 'tTable'.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
To transfer objects to different schema you use &lt;a href="http://msdn.microsoft.com/en-us/library/ms173423.aspx" target="_blank"&gt;ALTER SCHEMA&lt;/a&gt; statement.&lt;br /&gt;
&lt;div class="csharpcode-wrapper" id="codeSnippetWrapper"&gt;
&lt;div class="csharpcode" id="codeSnippet"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span class="kwrd"&gt;alter&lt;/span&gt; &lt;span class="kwrd"&gt;schema&lt;/span&gt; dbo transfer [Amilo\Ola].[tTable]&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum3"&gt;   3:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum4"&gt;   4:&lt;/span&gt; &lt;span class="kwrd"&gt;drop&lt;/span&gt; &lt;span class="kwrd"&gt;schema&lt;/span&gt; [Amilo\Ola]&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum5"&gt;   5:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum6"&gt;   6:&lt;/span&gt; &lt;span class="kwrd"&gt;drop&lt;/span&gt; &lt;span class="kwrd"&gt;user&lt;/span&gt; [Amilo\Ola]&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum7"&gt;   7:&lt;/span&gt; go&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
Ok, this would conclude this post. In summary, you should check your scripts and databases and verify that the users are created with &lt;b&gt;CREATE USER&lt;/b&gt; and with proper default schemas – it doesn’t always have to be the same schema as the users’s name. &lt;br /&gt;
Avoid implicit creation of users with sp_setapprole – this works only for Windows logins and you have to explicitly grant CONNECT right. Don’t use &lt;a href="http://msdn.microsoft.com/en-us/library/ms181422.aspx" target="_blank"&gt;sp_adduser&lt;/a&gt; either – it will be removed in future version of SQL Server.&lt;br /&gt;
&lt;br /&gt;
Objects created without explicit schemas will be created in user’s default schemas – and they may have pretty ugly names [Domain\Username].&lt;br /&gt;
&lt;br /&gt;
You will run into various security issues when using these objects and when you try to drop users from database.&lt;br /&gt;
&lt;br /&gt;
For completeness of the scripts on this page, here is the cleanup snippet:&lt;br /&gt;
&lt;div class="csharpcode-wrapper" id="codeSnippetWrapper"&gt;
&lt;div class="csharpcode" id="codeSnippet"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum1"&gt;   1:&lt;/span&gt; ---cleanup&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span class="kwrd"&gt;use&lt;/span&gt; master&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum3"&gt;   3:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum4"&gt;   4:&lt;/span&gt; &lt;span class="kwrd"&gt;drop&lt;/span&gt; &lt;span class="kwrd"&gt;database&lt;/span&gt; TestSchemaDb&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum5"&gt;   5:&lt;/span&gt; &lt;span class="kwrd"&gt;drop&lt;/span&gt; login frank&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum6"&gt;   6:&lt;/span&gt; &lt;span class="kwrd"&gt;drop&lt;/span&gt; login [Amilo\Ola]&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum7"&gt;   7:&lt;/span&gt; &lt;span class="kwrd"&gt;go&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:87852b46-2f18-4afd-a7e8-f2832e22b07f" style="display: inline; float: none; margin: 0px; padding: 0px;"&gt;
Technorati Tags: &lt;a href="http://technorati.com/tags/tips+and+tricks" rel="tag"&gt;tips and tricks&lt;/a&gt;,&lt;a href="http://technorati.com/tags/SQL+Server" rel="tag"&gt;SQL Server&lt;/a&gt;,&lt;a href="http://technorati.com/tags/T-SQL" rel="tag"&gt;T-SQL&lt;/a&gt;,&lt;a href="http://technorati.com/tags/programming" rel="tag"&gt;programming&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/902486075140485537-5521034858502458662?l=usepubs.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=kM8ZtIFTKdU:RcA7jWymoSo:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=kM8ZtIFTKdU:RcA7jWymoSo:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=kM8ZtIFTKdU:RcA7jWymoSo:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=kM8ZtIFTKdU:RcA7jWymoSo:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=kM8ZtIFTKdU:RcA7jWymoSo:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=kM8ZtIFTKdU:RcA7jWymoSo:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=kM8ZtIFTKdU:RcA7jWymoSo:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=kM8ZtIFTKdU:RcA7jWymoSo:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=kM8ZtIFTKdU:RcA7jWymoSo:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=kM8ZtIFTKdU:RcA7jWymoSo:3QFJfmc7Om4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=kM8ZtIFTKdU:RcA7jWymoSo:3QFJfmc7Om4" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PiotrRodak/~4/kM8ZtIFTKdU" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PiotrRodak/~3/kM8ZtIFTKdU/spaddrolemember-implicit-create-user.html</link><author>noreply@blogger.com (Piotr Rodak)</author><thr:total>0</thr:total><feedburner:origLink>http://usepubs.blogspot.com/2010/06/spaddrolemember-implicit-create-user.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-902486075140485537.post-3022931236989819859</guid><pubDate>Sun, 06 Jun 2010 22:50:00 +0000</pubDate><atom:updated>2010-06-22T22:48:49.311+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">t-sql</category><category domain="http://www.blogger.com/atom/ns#">tips and tricks</category><category domain="http://www.blogger.com/atom/ns#">SQLServerPedia Syndication</category><category domain="http://www.blogger.com/atom/ns#">code</category><category domain="http://www.blogger.com/atom/ns#">programming</category><category domain="http://www.blogger.com/atom/ns#">script</category><title>How to prepare sample data</title><description>Recently someone on one of SQL Server forums had a question how to prepare sample data so users can work on database restored from production. The requirement was that testers must not know the real data, names, addresses, emails and so on. On the other hand, users find very hard to work with totally random strings, like xwzr as first name, for example.&lt;br /&gt;
There are several tools on the market that help to prepare sample data. One of them is &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=bb3ad767-5f69-4db9-b1c9-8f55759846ed&amp;amp;displaylang=en" target="_blank"&gt;Visual Studio Database Edition&lt;/a&gt;, the other is &lt;a href="http://www.red-gate.com/products/SQL_Data_Generator/index.htm?utm_source=google&amp;amp;utm_medium=cpc&amp;amp;utm_content=brand_aware&amp;amp;utm_campaign=sqldatagenerator&amp;amp;gclid=CIKGtqGvjKICFQhBlAodQ1HKTw" target="_blank"&gt;SQL Data Generator&lt;/a&gt; from RedGate. I am sure there are many more.&lt;br /&gt;
The drawback of the above two excellent products is that they are not free. In some cases this is a major obstacle, because bosses are somehow not as likely to spend money for your tools (and toys) as you would like them to be.&lt;br /&gt;
So sometimes you have to implement sample data generator yourself. As it turns out, it is not too complicated (especially for simple cases).&lt;br /&gt;
Let’s assume that we want to replace all names in Person.Contact table in AdventureWorks database.&lt;br /&gt;
There are 19972 rows in this table in my database. I would like to replace all FirstName, MiddleName and LastName values with values that I prepare. Obviously, it is not so easy to come up with 20000 other names which don’t belong to &lt;a href="http://en.wikipedia.org/wiki/Klingon_language" target="_blank"&gt;Klingon language&lt;/a&gt;.&lt;br /&gt;
But if you think about this, 20000 is 50 x 40 x 10. If you have one fifty first names, forty last names and ten middle names, you can create 20000 unique combinations of these. You can easily find lists of names if you search, but for example &lt;a href="http://names.mongabay.com/most_common_surnames.htm" target="_blank"&gt;this page&lt;/a&gt; contains all names that we might need to populate 20000 rows.&lt;br /&gt;
For this example, I created three tables, each for separate list of names:&lt;br /&gt;
&lt;div class="csharpcode-wrapper" id="codeSnippetWrapper"&gt;
&lt;div class="csharpcode" id="codeSnippet"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;create&lt;/span&gt; &lt;span class="kwrd"&gt;table&lt;/span&gt; #RandomLastNames(RandomName nvarchar(50))&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span class="kwrd"&gt;create&lt;/span&gt; &lt;span class="kwrd"&gt;table&lt;/span&gt; #RandomFirstNames(RandomName nvarchar(50))&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum3"&gt;   3:&lt;/span&gt; &lt;span class="kwrd"&gt;create&lt;/span&gt; &lt;span class="kwrd"&gt;table&lt;/span&gt; #RandomMiddleNames(RandomName nvarchar(50))&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
I populated them using the names I found on the page I linked before. For middle names, I just typed in several initials and a NULL value, as NULLs are present in MiddleName column in Person Contact.&lt;br /&gt;
&lt;div class="csharpcode-wrapper" id="codeSnippetWrapper"&gt;
&lt;br /&gt;
&lt;div class="csharpcode" id="codeSnippet"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum1"&gt;   1:&lt;/span&gt; insert #RandomMiddleNames (RandomName)&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; N&lt;span class="str"&gt;'J.'&lt;/span&gt; &lt;span class="kwrd"&gt;union&lt;/span&gt; &lt;span class="kwrd"&gt;all&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum3"&gt;   3:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; N&lt;span class="str"&gt;'T.'&lt;/span&gt; &lt;span class="kwrd"&gt;union&lt;/span&gt; &lt;span class="kwrd"&gt;all&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum4"&gt;   4:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; N&lt;span class="str"&gt;'R.'&lt;/span&gt; &lt;span class="kwrd"&gt;union&lt;/span&gt; &lt;span class="kwrd"&gt;all&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum5"&gt;   5:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; N&lt;span class="str"&gt;'A.'&lt;/span&gt; &lt;span class="kwrd"&gt;union&lt;/span&gt; &lt;span class="kwrd"&gt;all&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum6"&gt;   6:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; N&lt;span class="str"&gt;'C.'&lt;/span&gt; &lt;span class="kwrd"&gt;union&lt;/span&gt; &lt;span class="kwrd"&gt;all&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum7"&gt;   7:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; N&lt;span class="str"&gt;'M.'&lt;/span&gt; &lt;span class="kwrd"&gt;union&lt;/span&gt; &lt;span class="kwrd"&gt;all&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum8"&gt;   8:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; N&lt;span class="str"&gt;'W.'&lt;/span&gt; &lt;span class="kwrd"&gt;union&lt;/span&gt; &lt;span class="kwrd"&gt;all&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum9"&gt;   9:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; N&lt;span class="str"&gt;'D.'&lt;/span&gt; &lt;span class="kwrd"&gt;union&lt;/span&gt; &lt;span class="kwrd"&gt;all&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum10"&gt;  10:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; N&lt;span class="str"&gt;'S.'&lt;/span&gt; &lt;span class="kwrd"&gt;union&lt;/span&gt; &lt;span class="kwrd"&gt;all&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum11"&gt;  11:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; N&lt;span class="str"&gt;'K.'&lt;/span&gt; &lt;span class="kwrd"&gt;union&lt;/span&gt; &lt;span class="kwrd"&gt;all&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum12"&gt;  12:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; N&lt;span class="str"&gt;'Z.'&lt;/span&gt; &lt;span class="kwrd"&gt;union&lt;/span&gt; &lt;span class="kwrd"&gt;all&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum13"&gt;  13:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; NULL&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
To get number of combinations of the data you just select count from cartesian product of all three tables:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="csharpcode-wrapper" id="codeSnippetWrapper"&gt;
&lt;div class="csharpcode" id="codeSnippet"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; &lt;span class="kwrd"&gt;count&lt;/span&gt;(*) [&lt;span class="kwrd"&gt;No&lt;/span&gt; &lt;span class="kwrd"&gt;of&lt;/span&gt; combinations] &lt;span class="kwrd"&gt;from&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum2"&gt;   2:&lt;/span&gt; #RandomFirstNames &lt;span class="kwrd"&gt;cross&lt;/span&gt; &lt;span class="kwrd"&gt;join&lt;/span&gt; &lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum3"&gt;   3:&lt;/span&gt;     #RandomLastNames &lt;span class="kwrd"&gt;cross&lt;/span&gt; &lt;span class="kwrd"&gt;join&lt;/span&gt; &lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum4"&gt;   4:&lt;/span&gt;         #RandomMiddleNames&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
The rest is easy. To preview how data you have will be replaced you run this query:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="csharpcode-wrapper" id="codeSnippetWrapper"&gt;
&lt;div class="csharpcode" id="codeSnippet"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;select&lt;/span&gt; cn.ContactID, cn.FirstName + N&lt;span class="str"&gt;' '&lt;/span&gt; + isnull(cn.MiddleName + N&lt;span class="str"&gt;' '&lt;/span&gt;, N&lt;span class="str"&gt;''&lt;/span&gt;) + cn.LastName OriginalData,&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum2"&gt;   2:&lt;/span&gt; (&lt;span class="kwrd"&gt;select&lt;/span&gt; &lt;span class="kwrd"&gt;top&lt;/span&gt; 1 RandomName &lt;span class="kwrd"&gt;from&lt;/span&gt; #RandomFirstNames &lt;span class="kwrd"&gt;where&lt;/span&gt; cn.ContactId = cn.ContactId &lt;span class="kwrd"&gt;order&lt;/span&gt; &lt;span class="kwrd"&gt;by&lt;/span&gt; newid()) FirstName, &lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum3"&gt;   3:&lt;/span&gt; (&lt;span class="kwrd"&gt;select&lt;/span&gt; &lt;span class="kwrd"&gt;top&lt;/span&gt; 1 RandomName &lt;span class="kwrd"&gt;from&lt;/span&gt; #RandomMiddleNames &lt;span class="kwrd"&gt;where&lt;/span&gt; cn.ContactId = cn.ContactId &lt;span class="kwrd"&gt;order&lt;/span&gt; &lt;span class="kwrd"&gt;by&lt;/span&gt; newid()) MiddleName, &lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum4"&gt;   4:&lt;/span&gt; (&lt;span class="kwrd"&gt;select&lt;/span&gt; &lt;span class="kwrd"&gt;top&lt;/span&gt; 1 RandomName &lt;span class="kwrd"&gt;from&lt;/span&gt; #RandomLastNames &lt;span class="kwrd"&gt;where&lt;/span&gt; cn.ContactId = cn.ContactId &lt;span class="kwrd"&gt;order&lt;/span&gt; &lt;span class="kwrd"&gt;by&lt;/span&gt; newid()) LastName&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum5"&gt;   5:&lt;/span&gt; &lt;span class="kwrd"&gt;into&lt;/span&gt; #DataMapping&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum6"&gt;   6:&lt;/span&gt; &lt;span class="kwrd"&gt;from&lt;/span&gt; Person.Contact cn&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
To actually update the data just run this update:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="csharpcode-wrapper" id="codeSnippetWrapper"&gt;
&lt;div class="csharpcode" id="codeSnippet"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum1"&gt;   1:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span class="kwrd"&gt;update&lt;/span&gt; Person.Contact &lt;span class="kwrd"&gt;set&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum3"&gt;   3:&lt;/span&gt; FirstName = b.FirstName,&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum4"&gt;   4:&lt;/span&gt; MiddleName = b.MiddleName,&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum5"&gt;   5:&lt;/span&gt; LastName = b.LastName&lt;/pre&gt;
&lt;pre class="alteven"&gt;&lt;span class="lnum" id="lnum6"&gt;   6:&lt;/span&gt; &lt;span class="kwrd"&gt;from&lt;/span&gt; Person.Contact a &lt;span class="kwrd"&gt;inner&lt;/span&gt; &lt;span class="kwrd"&gt;join&lt;/span&gt; &lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum" id="lnum7"&gt;   7:&lt;/span&gt;         #DataMapping b &lt;span class="kwrd"&gt;on&lt;/span&gt; a.ContactId = b.ContactId&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
And that’s it! You can modify the script I attach to suit your needs, you can modify other data the same way, like emails, address lines etc.&lt;br /&gt;
&lt;br /&gt;
Sample code &lt;a href="https://docs.google.com/uc?id=0B5ayjYKh-6TxMDM1NzA0MjctMzBiMi00ZDY3LWI4Y2EtODcxMjdmNzk0NDMy&amp;amp;export=download&amp;amp;hl=en" target="_blank"&gt;download here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:2bfeed38-a079-479b-bd8b-f2541b7092d0" style="display: inline; float: none; margin: 0px; padding: 0px;"&gt;
Technorati Tags: &lt;a href="http://technorati.com/tags/SQL+Server" rel="tag"&gt;SQL Server&lt;/a&gt;,&lt;a href="http://technorati.com/tags/programming" rel="tag"&gt;programming&lt;/a&gt;,&lt;a href="http://technorati.com/tags/code" rel="tag"&gt;code&lt;/a&gt;,&lt;a href="http://technorati.com/tags/tips+and+tricks" rel="tag"&gt;tips and tricks&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/902486075140485537-3022931236989819859?l=usepubs.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=vQF8m4fO6NU:gQQs9rvnYBM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=vQF8m4fO6NU:gQQs9rvnYBM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=vQF8m4fO6NU:gQQs9rvnYBM:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=vQF8m4fO6NU:gQQs9rvnYBM:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=vQF8m4fO6NU:gQQs9rvnYBM:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=vQF8m4fO6NU:gQQs9rvnYBM:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=vQF8m4fO6NU:gQQs9rvnYBM:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=vQF8m4fO6NU:gQQs9rvnYBM:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=vQF8m4fO6NU:gQQs9rvnYBM:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=vQF8m4fO6NU:gQQs9rvnYBM:3QFJfmc7Om4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=vQF8m4fO6NU:gQQs9rvnYBM:3QFJfmc7Om4" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PiotrRodak/~4/vQF8m4fO6NU" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PiotrRodak/~3/vQF8m4fO6NU/how-to-prepare-sample-data.html</link><author>noreply@blogger.com (Piotr Rodak)</author><thr:total>0</thr:total><feedburner:origLink>http://usepubs.blogspot.com/2010/06/how-to-prepare-sample-data.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-902486075140485537.post-6996138563857055753</guid><pubDate>Wed, 02 Jun 2010 20:08:00 +0000</pubDate><atom:updated>2010-06-02T21:21:25.269+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">t-sql</category><category domain="http://www.blogger.com/atom/ns#">tips and tricks</category><category domain="http://www.blogger.com/atom/ns#">code</category><category domain="http://www.blogger.com/atom/ns#">programming</category><category domain="http://www.blogger.com/atom/ns#">good practices</category><category domain="http://www.blogger.com/atom/ns#">script</category><title>Save the time – use roles!</title><description>Some time ago I wrote about &lt;a href="http://sqlblogcasts.com/blogs/piotr_rodak/archive/2010/05/24/good-practices-database-programming-unit-testing.aspx" target="_blank"&gt;coding practices&lt;/a&gt;. I would like to follow this topic with a quick post about making the life easier.&lt;br /&gt;
If you happen to be a developer who also is responsible for managing development databases and access of other team members to the environment, you might find this tip useful.&lt;br /&gt;
&lt;h5 align="center"&gt;&lt;span style="font-size: large;"&gt;Create role for developers and assign rights to it. &lt;/span&gt;&lt;/h5&gt;Usually you would want developers to be able to run DDL commands and also execute procedures and write and read data. I’ve seen many times that developers were given the db_owner role. This is in most cases too much. If you have specific custom role, you can easily adjust the security settings without having to browse through all users. &lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border: 1px solid silver; cursor: text; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding: 4px; text-align: left; width: 97.5%;"&gt;&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-style: none; color: black; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding: 0px; text-align: left; width: 100%;"&gt;&lt;pre style="background-color: white; border-style: none; color: black; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;use&lt;/span&gt; TestDB&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-style: none; color: black; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;go&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: white; border-style: none; color: black; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt; &lt;span style="color: blue;"&gt;create&lt;/span&gt; &lt;span style="color: blue;"&gt;role&lt;/span&gt; [DBDeveloper] &lt;span style="color: blue;"&gt;authorization&lt;/span&gt; dbo&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-style: none; color: black; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt; &lt;span style="color: blue;"&gt;go&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: white; border-style: none; color: black; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt; &lt;span style="color: blue;"&gt;grant&lt;/span&gt; &lt;span style="color: blue;"&gt;execute&lt;/span&gt; &lt;span style="color: blue;"&gt;to&lt;/span&gt; DBDeveloper&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-style: none; color: black; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt; &lt;span style="color: blue;"&gt;go&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: white; border-style: none; color: black; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum7" style="color: #606060;"&gt;   7:&lt;/span&gt; &lt;span style="color: blue;"&gt;exec&lt;/span&gt; sp_addrolemember &lt;span style="color: #006080;"&gt;'db_ddladmin'&lt;/span&gt;, &lt;span style="color: #006080;"&gt;'DBDeveloper'&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-style: none; color: black; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum8" style="color: #606060;"&gt;   8:&lt;/span&gt; &lt;span style="color: blue;"&gt;exec&lt;/span&gt; sp_addrolemember &lt;span style="color: #006080;"&gt;'db_datawriter'&lt;/span&gt;, &lt;span style="color: #006080;"&gt;'DBDeveloper'&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: white; border-style: none; color: black; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum9" style="color: #606060;"&gt;   9:&lt;/span&gt; &lt;span style="color: blue;"&gt;exec&lt;/span&gt; sp_addrolemember &lt;span style="color: #006080;"&gt;'db_datareader'&lt;/span&gt;, &lt;span style="color: #006080;"&gt;'DBDeveloper'&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-style: none; color: black; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum10" style="color: #606060;"&gt;  10:&lt;/span&gt; &lt;span style="color: blue;"&gt;go&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
As you see above, I create role &lt;i&gt;DBDeveloper&lt;/i&gt; and grant several rights to the role. Next, I just need to add users to the role to give them what they need.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border: 1px solid silver; cursor: text; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding: 4px; text-align: left; width: 97.5%;"&gt;&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-style: none; color: black; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding: 0px; text-align: left; width: 100%;"&gt;&lt;pre style="background-color: white; border-style: none; color: black; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;use&lt;/span&gt; master&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-style: none; color: black; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;go&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-style: none; color: black; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt; &lt;span style="color: blue;"&gt;create&lt;/span&gt; login [frank] &lt;span style="color: blue;"&gt;from&lt;/span&gt; windows &lt;span style="color: blue;"&gt;with&lt;/span&gt; default_language=us_english&lt;span id="lnum4" style="color: #606060;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-style: none; color: black; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt; &lt;span style="color: blue;"&gt;go&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: white; border-style: none; color: black; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt; &lt;span style="color: blue;"&gt;use&lt;/span&gt; TestDB&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-style: none; color: black; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt; &lt;span style="color: blue;"&gt;go&lt;/span&gt;&lt;span id="lnum7" style="color: #606060;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-style: none; color: black; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum7" style="color: #606060;"&gt;   7:&lt;/span&gt; &lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-style: none; color: black; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum8" style="color: #606060;"&gt;   8:&lt;/span&gt; &lt;span style="color: blue;"&gt;create&lt;/span&gt; &lt;span style="color: blue;"&gt;user&lt;/span&gt; [frank] &lt;span style="color: blue;"&gt;from&lt;/span&gt; login [frank] &lt;span style="color: blue;"&gt;with&lt;/span&gt; default_schema=dbo&lt;/pre&gt;&lt;pre style="background-color: white; border-style: none; color: black; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum9" style="color: #606060;"&gt;   9:&lt;/span&gt; &lt;span style="color: blue;"&gt;go&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-style: none; color: black; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum10" style="color: #606060;"&gt;  10:&lt;/span&gt; &lt;span style="color: blue;"&gt;exec&lt;/span&gt; sp_addrolemember &lt;span style="color: #006080;"&gt;'DBDeveloper'&lt;/span&gt;, &lt;span style="color: #006080;"&gt;'frank'&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: white; border-style: none; color: black; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum11" style="color: #606060;"&gt;  11:&lt;/span&gt; go&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
This little trick saves a lot of time and hassle, and if you save these scripts carefully, you can easily restore security on a database refreshed from production for example.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:cd0ee5a8-f83a-43d2-834d-accc10291386" style="display: inline; float: none; margin: 0px; padding: 0px;"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/SQL+Server" rel="tag"&gt;SQL Server&lt;/a&gt;,&lt;a href="http://technorati.com/tags/T-SQL" rel="tag"&gt;T-SQL&lt;/a&gt;,&lt;a href="http://technorati.com/tags/tips+and+tricks" rel="tag"&gt;tips and tricks&lt;/a&gt;,&lt;a href="http://technorati.com/tags/programming" rel="tag"&gt;programming&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/902486075140485537-6996138563857055753?l=usepubs.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=IDOPiMxhfQU:l_ngTP-UvXc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=IDOPiMxhfQU:l_ngTP-UvXc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=IDOPiMxhfQU:l_ngTP-UvXc:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=IDOPiMxhfQU:l_ngTP-UvXc:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=IDOPiMxhfQU:l_ngTP-UvXc:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=IDOPiMxhfQU:l_ngTP-UvXc:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=IDOPiMxhfQU:l_ngTP-UvXc:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=IDOPiMxhfQU:l_ngTP-UvXc:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=IDOPiMxhfQU:l_ngTP-UvXc:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=IDOPiMxhfQU:l_ngTP-UvXc:3QFJfmc7Om4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=IDOPiMxhfQU:l_ngTP-UvXc:3QFJfmc7Om4" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PiotrRodak/~4/IDOPiMxhfQU" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PiotrRodak/~3/IDOPiMxhfQU/save-time-use-roles.html</link><author>noreply@blogger.com (Piotr Rodak)</author><thr:total>0</thr:total><feedburner:origLink>http://usepubs.blogspot.com/2010/06/save-time-use-roles.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-902486075140485537.post-7260947132978718998</guid><pubDate>Sun, 30 May 2010 23:13:00 +0000</pubDate><atom:updated>2010-05-31T00:13:02.640+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">welcome</category><title>Hey there!</title><description>Hi everyone :)&lt;br /&gt;
This is my first post here, though not first post in my life. My old blog is here: &lt;a href="http://sqlblogcasts.com/blogs/piotr_rodak/"&gt;http://sqlblogcasts.com/blogs/piotr_rodak/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
I decided to move my blog to have more flexibility and perhaps slightly better blogging platform. I am going to continue writing about SQL Server, problems that I faced and sometimes solved, tips and tricks, coding practices and a lot more - we'll see what future will bring.&lt;br /&gt;
&lt;br /&gt;
I hope that you will find this blog interesting :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/902486075140485537-7260947132978718998?l=usepubs.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=pOpjfGS_4s0:EiogBKXvm-c:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=pOpjfGS_4s0:EiogBKXvm-c:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=pOpjfGS_4s0:EiogBKXvm-c:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=pOpjfGS_4s0:EiogBKXvm-c:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=pOpjfGS_4s0:EiogBKXvm-c:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=pOpjfGS_4s0:EiogBKXvm-c:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=pOpjfGS_4s0:EiogBKXvm-c:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=pOpjfGS_4s0:EiogBKXvm-c:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=pOpjfGS_4s0:EiogBKXvm-c:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PiotrRodak?a=pOpjfGS_4s0:EiogBKXvm-c:3QFJfmc7Om4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PiotrRodak?i=pOpjfGS_4s0:EiogBKXvm-c:3QFJfmc7Om4" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PiotrRodak/~4/pOpjfGS_4s0" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PiotrRodak/~3/pOpjfGS_4s0/hey-there.html</link><author>noreply@blogger.com (Piotr Rodak)</author><thr:total>0</thr:total><feedburner:origLink>http://usepubs.blogspot.com/2010/05/hey-there.html</feedburner:origLink></item></channel></rss>

