<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.geekdojo.net/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>&amp;lt;Nathan H. Omukwenyi&amp;gt;</title><link>http://blogs.geekdojo.net/nathan/default.aspx</link><description>{The view from a very fast moving technology train};</description><dc:language>en-US</dc:language><generator>CommunityServer 2.0 (Build: 60217.2664)</generator><item><title>Multiple Parameter Scalar MAX() function</title><link>http://blogs.geekdojo.net/nathan/archive/2010/01/27/2022299422.aspx</link><pubDate>Wed, 27 Jan 2010 09:10:13 GMT</pubDate><guid isPermaLink="false">8c778905-0e18-4c86-9fd6-6e26bc083633:2022299422</guid><dc:creator>nathan</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.geekdojo.net/nathan/comments/2022299422.aspx</comments><wfw:commentRss>http://blogs.geekdojo.net/nathan/commentrss.aspx?PostID=2022299422</wfw:commentRss><wfw:comment>http://blogs.geekdojo.net/rsscomments/2022299422.aspx</wfw:comment><description>&lt;p&gt;T-SQL provides functions for determining the greatest and the lowest values in a column of data using the MAX() and MIN() aggregate functions respectively. The functions only work with one variable and may require the use of the GROUP BY clause if other columns of the same table are included in the SELECT list. This means that if you wanted to get the higher of any two independent variables or columns just like the .NET Math.Max() function, you would have to write your own implementation or convert the independent variables into a set (i.e. a one column table variable).&lt;/p&gt;  &lt;p&gt;Consider the following the table and data:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;div id="codeSnippet"&gt;     &lt;pre&gt;&lt;span id="lnum1"&gt;   1:&lt;/span&gt; &lt;span&gt;CREATE&lt;/span&gt; &lt;span&gt;TABLE&lt;/span&gt; t1(col1 &lt;span&gt;int&lt;/span&gt;, col2 &lt;span&gt;int&lt;/span&gt;,col3 &lt;span&gt;int&lt;/span&gt;);&lt;/pre&gt;


    &lt;pre&gt;&lt;span id="lnum2"&gt;   2:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre&gt;&lt;span id="lnum3"&gt;   3:&lt;/span&gt; &lt;span&gt;GO&lt;/span&gt;&lt;/pre&gt;


    &lt;pre&gt;&lt;span id="lnum4"&gt;   4:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre&gt;&lt;span id="lnum5"&gt;   5:&lt;/span&gt; INSERT &lt;span&gt;INTO&lt;/span&gt; t1 &lt;span&gt;VALUES&lt;/span&gt;(1,0,1),(2,1,0),(3,1,&lt;span&gt;NULL&lt;/span&gt;),(4,&lt;span&gt;NULL&lt;/span&gt;,1),(5,&lt;span&gt;NULL&lt;/span&gt;,&lt;span&gt;NULL&lt;/span&gt;)&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Supposing we want to pick the greater of the 2 columns (col1 and col2) for each row in the table, the easiest route would be to use a CASE statement like this:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div id="codeSnippet"&gt;
    &lt;pre&gt;&lt;span id="lnum1"&gt;   1:&lt;/span&gt; &lt;span&gt;SELECT&lt;/span&gt; col1, &lt;span&gt;CASE&lt;/span&gt; &lt;span&gt;WHEN&lt;/span&gt; col2 &amp;gt; col3 &lt;span&gt;THEN&lt;/span&gt; col2 &lt;span&gt;ELSE&lt;/span&gt; col3 &lt;span&gt;END&lt;/span&gt; &lt;span&gt;AS&lt;/span&gt; greaterCol&lt;/pre&gt;


    &lt;pre&gt;&lt;span id="lnum2"&gt;   2:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre&gt;&lt;span id="lnum3"&gt;   3:&lt;/span&gt; &lt;span&gt;FROM&lt;/span&gt; t1;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;This would return the following results.&lt;/p&gt;

&lt;div id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:67b1c3e1-0832-4f77-ae95-490e2c72513a" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: text"&gt;col1        greaterCol
----------- -----------
1           1
2           1
3           NULL
4           1
5           NULL
5           1&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The result for the 3&lt;sup&gt;rd&lt;/sup&gt; row may not be correct if in ‘our design’, we were expecting 1 to be greater than NULL. SQL Server (and NULL logic), will give different results for comparisons with ‘unknowns’. Apparently, the answer depends on which column is on the right hand side of the comparison. &lt;/p&gt;

&lt;p&gt;To get the correct results, we could modify our query like this.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div id="codeSnippet"&gt;
    &lt;pre&gt;&lt;span id="lnum1"&gt;   1:&lt;/span&gt; &lt;span&gt;SELECT&lt;/span&gt; col1, &lt;/pre&gt;


    &lt;pre&gt;&lt;span id="lnum2"&gt;   2:&lt;/span&gt;     &lt;span&gt;CASE&lt;/span&gt; &lt;span&gt;WHEN&lt;/span&gt; ISNULL(col2,0) &amp;gt; ISNULL(col3,0) &lt;span&gt;THEN&lt;/span&gt; col2 &lt;span&gt;ELSE&lt;/span&gt; col3 &lt;span&gt;END&lt;/span&gt; &lt;span&gt;AS&lt;/span&gt; greaterCol&lt;/pre&gt;


    &lt;pre&gt;&lt;span id="lnum3"&gt;   3:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre&gt;&lt;span id="lnum4"&gt;   4:&lt;/span&gt; &lt;span&gt;FROM&lt;/span&gt; t1;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;We could also implement our own MAX () function that takes 2 parameters and returns the greater value. Of course, our function should be able to handle NULLs appropriately. The user-defined MAX () function looks like the listing below:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;CREATE&lt;/span&gt; &lt;span class="kwrd"&gt;FUNCTION&lt;/span&gt; dbo.&lt;span class="kwrd"&gt;MAX&lt;/span&gt;(@val1 &lt;span class="kwrd"&gt;int&lt;/span&gt;,@val2 &lt;span class="kwrd"&gt;int&lt;/span&gt;)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;&lt;span class="kwrd"&gt;RETURNS&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;&lt;span class="kwrd"&gt;AS&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;&lt;span class="kwrd"&gt;BEGIN&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;&lt;span class="kwrd"&gt;IF&lt;/span&gt; ISNULL(@val1 , 0) &amp;gt;= ISNULL(@val2 , 0)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:      &lt;/span&gt;&lt;span class="kwrd"&gt;RETURN&lt;/span&gt; @val1;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;&lt;span class="kwrd"&gt;RETURN&lt;/span&gt; @val2;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;&lt;span class="kwrd"&gt;END&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }

&lt;p&gt;and use it (repeatedly if we wish), like this:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div id="codeSnippet"&gt;
    &lt;pre&gt;&lt;span id="lnum1"&gt;   1:&lt;/span&gt; &lt;span&gt;SELECT&lt;/span&gt; col1, dbo.&lt;span&gt;MAX&lt;/span&gt;(col2,col3) &lt;span&gt;AS&lt;/span&gt; greaterCol &lt;span&gt;FROM&lt;/span&gt; t1;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The user-defined function, as created above, is limited to one explicit data type and we may have to change its definition to cater for more comparable data types. It is also limited to only 2 parameters, although I am sure we can extend it to accept more parameters with some recursive code. &lt;/p&gt;

&lt;p&gt;Despite the ease of usage, the dbo.MAX () function, may be a tad slower than the CASE version for very large tables and the CASE statement seems to benefit from parallelism.&lt;/p&gt;

&lt;p&gt;As an aside, for the functionality discussed above, Oracle PL/SQL provides the &lt;strong&gt;GREATEST ()&lt;/strong&gt; and &lt;strong&gt;LEAST ()&lt;/strong&gt; functions. The beauty of these functions is that they can accept more than 2 parameters. The downside is that they intrinsically return NULL if any of the parameters is a NULL value – no fault on Oracle’s part since the functions are intended to be ANSI compliant.&lt;/p&gt;

&lt;p&gt;I wonder why Microsoft has not bothered to provide similar (or better) functionality&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:74392e13-6dcf-4337-b069-e1dd3698cd9c" class="wlWriterEditableSmartContent"&gt;del.icio.us Tags: &lt;a href="http://del.icio.us/popular/T-SQL" rel="tag"&gt;T-SQL&lt;/a&gt;,&lt;a href="http://del.icio.us/popular/MAX()+function" rel="tag"&gt;MAX() function&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blogs.geekdojo.net/aggbug.aspx?PostID=2022299422" width="1" height="1"&gt;</description><category domain="http://blogs.geekdojo.net/nathan/archive/category/126.aspx">Technical</category><category domain="http://blogs.geekdojo.net/nathan/archive/category/127.aspx">Rants</category></item><item><title>T-SQL Damerau–Levenshtein Distance</title><link>http://blogs.geekdojo.net/nathan/archive/2010/01/22/2022299405.aspx</link><pubDate>Fri, 22 Jan 2010 19:42:20 GMT</pubDate><guid isPermaLink="false">8c778905-0e18-4c86-9fd6-6e26bc083633:2022299405</guid><dc:creator>nathan</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.geekdojo.net/nathan/comments/2022299405.aspx</comments><wfw:commentRss>http://blogs.geekdojo.net/nathan/commentrss.aspx?PostID=2022299405</wfw:commentRss><wfw:comment>http://blogs.geekdojo.net/rsscomments/2022299405.aspx</wfw:comment><description>&lt;p&gt;The &lt;a href="http://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance" target="_blank"&gt;Damerau–Levenshtein distance&lt;/a&gt; or the “edit distance” between two strings can be used in SQL Server database applications to search for strings when you’ve reached the limit with the LIKE clause or the full-text indexing features. Used directly in T-SQL, the algorithm has some obvious limitations like:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;When used for fuzzy matches, the strings need to be relatively short&amp;#160; since the algorithm operates in the worst case at O(m*n) where m and n are the respective string lengths. This fact can be made worse if the algorithm is called as a scalar-valued function as part of a multi-column select over a very large table. The entire search then runs at O(k*m*n*) where k is the row count. &lt;/li&gt;    &lt;li&gt;There is little(no) chance of the query optimizer using any indexes on the searched column when you use the algorithm in your WHERE clause. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Those grim facts aside and the debatable instinct that you ought to consider implementing this either using LINQ or just plain .NET, here is my adapted T-SQL version of the Damerau–Levenshtein distance.&lt;/p&gt;  &lt;p&gt;CREATE FUNCTION DamerauLevenshteinDistance(@str1 varchar(max), @str2 varchar(max))    &lt;br /&gt;RETURNS int     &lt;br /&gt;AS     &lt;br /&gt;BEGIN     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; DECLARE @str1_len int=(SELECT DATALENGTH(@str1));     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; DECLARE @str2_len int=(SELECT DATALENGTH(@str2));     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if (@str1 IS NULL AND @str2 IS NULL)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return 0; &lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; if (@str1 IS null)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return @str2_len     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if (@str2 IS null)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return @str1_len; &lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; -- matrix that stores cumulative scores as strings are traversed    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; DECLARE @d TABLE (i int NULL,j int NULL,value int NULL)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; declare @i int, @j int, @cost int;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; -- fill in scores for first row and column     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SET @i = 0;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; WHILE (@i &amp;lt;= @str1_len)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; BEGIN     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; INSERT into @d (i,j,value) VALUES(@i,0,@i)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; SET @i +=1;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; END     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SET @j = 0;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; WHILE (@j &amp;lt;= @str2_len)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; BEGIN     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; INSERT into @d (i,j,value) VALUES(0,@j,@j)&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; SET @j +=1;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; END     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; declare @newvalue int;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; declare @x int;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; declare @y int;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; declare @z int;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; declare @tcost int;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; declare @a int;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; declare @b int;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SET @i = 1;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; WHILE (@i &amp;lt;= @str1_len)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; BEGIN     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; SET @j = 1;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WHILE (@j &amp;lt;= @str2_len)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; BEGIN     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (SUBSTRING(@str1,@i,1) = SUBSTRING(@str2,@j,1))&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; set @cost = 0;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; else     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; set @cost = 1; &lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; -- addition, subtraction, substitution costs    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; set @x=(SELECT value + 1 from @d WHERE i=@i - 1 AND j=@j);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; set @y=(SELECT value + 1 from @d WHERE i=@i AND j=@j-1);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; set @z=(SELECT DISTINCT value from @d WHERE i=@i-1 AND j=@j-1);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; set @z += @cost;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; SET @newvalue=dbo.Minimum(dbo.Minimum(@x, @y),@z);&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; INSERT into @d (i,j,value) VALUES(@i,@j,@newvalue)&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (@i &amp;gt; 1 AND @j &amp;gt; 1 AND SUBSTRING(@str1,@i,1) = SUBSTRING(@str2,@j - 1,1) AND SUBSTRING(@str1,@i - 1,1) = SUBSTRING(@str2,@j,1))     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; BEGIN&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; -- transposition cost     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; set @a=(SELECT value from @d WHERE i=@i AND j=@j);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; set @b=(SELECT DISTINCT value from @d WHERE i=@i - 2 AND j=@j-2);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; set @b +=@cost;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; set @tcost=dbo.Minimum(@a,@b);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Update @d SET value=@tcost WHERE i=@i AND j=@j;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; END     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; SET @j +=1;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; END     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; SET @i +=1;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; END     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; declare @distance int=(select value from @d WHERE i=@str1_len AND j=@str2_len);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; return @distance;     &lt;br /&gt;END&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;The DL distance function above makes use of another scalar-valued function for getting the minimum of two numbers, &lt;strong&gt;Minimum,&lt;/strong&gt; shown below:&lt;/p&gt;  &lt;p&gt;CREATE FUNCTION Minimum(@val1 float, @val2 float)    &lt;br /&gt;RETURNS Float     &lt;br /&gt;AS     &lt;br /&gt;BEGIN     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; IF (@val1 &amp;lt; @val2)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; RETURN @val1;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; RETURN @val2;     &lt;br /&gt;END&lt;/p&gt;  &lt;p&gt;It is up to you to decide the DL distance that meets the threshold of relevance of your search.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:a9b8cd3a-0c0f-4be0-a11a-53ad1cdbe31d" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/Search" rel="tag"&gt;Search&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Damerau-Levenshtein" rel="tag"&gt;Damerau-Levenshtein&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Fuzzy" rel="tag"&gt;Fuzzy&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blogs.geekdojo.net/aggbug.aspx?PostID=2022299405" width="1" height="1"&gt;</description><category domain="http://blogs.geekdojo.net/nathan/archive/category/126.aspx">Technical</category></item><item><title>Word Clouds</title><link>http://blogs.geekdojo.net/nathan/archive/2009/02/13/2022294307.aspx</link><pubDate>Sat, 14 Feb 2009 07:30:47 GMT</pubDate><guid isPermaLink="false">8c778905-0e18-4c86-9fd6-6e26bc083633:2022294307</guid><dc:creator>nathan</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.geekdojo.net/nathan/comments/2022294307.aspx</comments><wfw:commentRss>http://blogs.geekdojo.net/nathan/commentrss.aspx?PostID=2022294307</wfw:commentRss><wfw:comment>http://blogs.geekdojo.net/rsscomments/2022294307.aspx</wfw:comment><description>&lt;p&gt;I recently stumbled upon this cool online toy by &lt;a href="http://blog.wordle.net/" target="_blank"&gt;Jonathan Feinberg&lt;/a&gt; from the &lt;a href="http://www.research.ibm.com/visual/" target="_blank"&gt;IBM Research Visual Communication Lab&lt;/a&gt;. It is called &lt;a href="http://wordle.net/" target="_blank"&gt;WORDLE&lt;/a&gt;, uses JQuery and generates "word clouds" from a bunch of text or any URL with an RSS feed. It is a tagging engine and if the gallery serves as an indicator of its usage, you will notice that people who have tried it range from one word bloggers to pundits analyzing American presidential inaugural speeches. I will confess that it is the latter that led me to this toy.&lt;/p&gt; &lt;p&gt;Well, I decided to plug in this blog and here is the result.&amp;nbsp; I wasn't terribly surprised by the Wordle analysis of my blog. I realize that the blog could benefit from more technical writing on SQL Server and .NET.&lt;/p&gt; &lt;p&gt;&lt;img alt="Wordle on Nathan's Blog" src="http://www.rwandadotnet.org/content/wordle_nathan.gif"&gt; &lt;/p&gt; &lt;p&gt;The only gripe I have with it is the fact that I had to change to my IE 7 security settings to medium and allow some worrying Microsoft VM Java options to make it work. I suspect that it has nothing to do with the tool itself but just a damning reminder of why I have always been wary of Java applets in general. &lt;/p&gt; &lt;p&gt;Since I have been fascinated with image generation for a while now, I am going to use this experience as a launching pad for my next .NET drawing and AJAX learning project. it would be interesting to do this in ASP.NET or WPF&lt;/p&gt;&lt;img src="http://blogs.geekdojo.net/aggbug.aspx?PostID=2022294307" width="1" height="1"&gt;</description><category domain="http://blogs.geekdojo.net/nathan/archive/category/125.aspx">What's going On</category></item><item><title>Structural Binding as a Best Practice</title><link>http://blogs.geekdojo.net/nathan/archive/2009/02/13/2022294303.aspx</link><pubDate>Fri, 13 Feb 2009 22:23:09 GMT</pubDate><guid isPermaLink="false">8c778905-0e18-4c86-9fd6-6e26bc083633:2022294303</guid><dc:creator>nathan</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.geekdojo.net/nathan/comments/2022294303.aspx</comments><wfw:commentRss>http://blogs.geekdojo.net/nathan/commentrss.aspx?PostID=2022294303</wfw:commentRss><wfw:comment>http://blogs.geekdojo.net/rsscomments/2022294303.aspx</wfw:comment><description>&lt;p&gt;SQL Server allows us to decide whether query objects we create referencing tables can be tightly or loosely bound to the table structure. When you create a view or stored procedure you can specify the WITH SCHEMABINDING option to indicate that the view or stored procedure is invalidated if the underlying table structure is modified. In such a situation, the developer will need to drop and recreate the view or stored procedure. It also, inadvertently , serves as a check against 'breaking' changes like dropping columns and changing column data types without regard for dependencies.&lt;/p&gt; &lt;p&gt;Most of the views I see in practice do not specify this option and a reasonable percentage use the "SELECT *" construct to retrieve data from the base tables. This means that if the underlying table(s) change, the developers will be scrambling to either fix bugs or if they are in the know, running &lt;strong&gt;sp_refreshview&lt;/strong&gt; to synchronize the view metadata. One of the practices I preach is the use of WITH SCHEMABINDING at all times. This will consequently force you &lt;/p&gt; &lt;ol&gt; &lt;li&gt;Not to use the "SELECT *" construct in your views at all. This makes total sense to me even without considering some positive performance points you might gain by specifying exactly what you need to retrieve from the database.&lt;/li&gt; &lt;li&gt;To use two part names for every column and table you reference i.e. table.column or schema.table.&lt;/li&gt; &lt;li&gt;To carefully consider making 'breaking' changes to your table structure. In any case, good and thorough designing at all tiers of your application should reduce the need for frequent structural changes at the table level. If you must change stuff, script these changes and apply them as part of a bug fix or patch. &lt;/li&gt; &lt;li&gt;To seriously re-evaluate your usage of nested views. Yes, I think that they are bad.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;I have not yet seen any single advantage (apart from excuses) of not tightly binding your references to tables in your database. If the guys at Redmond were listening, I would suggest that all views be implicitly schema bound instead of allowing the T-SQL developer to shoot themselves in the foot. In fact, it sounds better to me to have a WITH NOSCHEMABINDING option just in case some developer out there wanted to do the un-recommended.&lt;/p&gt;&lt;img src="http://blogs.geekdojo.net/aggbug.aspx?PostID=2022294303" width="1" height="1"&gt;</description><category domain="http://blogs.geekdojo.net/nathan/archive/category/126.aspx">Technical</category></item><item><title>Disorderly Views</title><link>http://blogs.geekdojo.net/nathan/archive/2008/08/05/2022290945.aspx</link><pubDate>Tue, 05 Aug 2008 08:51:44 GMT</pubDate><guid isPermaLink="false">8c778905-0e18-4c86-9fd6-6e26bc083633:2022290945</guid><dc:creator>nathan</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.geekdojo.net/nathan/comments/2022290945.aspx</comments><wfw:commentRss>http://blogs.geekdojo.net/nathan/commentrss.aspx?PostID=2022290945</wfw:commentRss><wfw:comment>http://blogs.geekdojo.net/rsscomments/2022290945.aspx</wfw:comment><description>&lt;p&gt;In SQL Server 2005, if you create a view utilizing the TOP (100) PERCENT and ORDER BY clauses, you will not get back your results in the order specified.&lt;/p&gt; &lt;p&gt;Example:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font color="#000080"&gt;USE&lt;/font&gt; AdventureWorks&lt;br&gt;GO&lt;br&gt;&lt;font color="#000080"&gt;CREATE VIEW&lt;/font&gt; CustomersOrderedbyTerritory&lt;br&gt;&lt;font color="#000080"&gt;AS&lt;br&gt;SELECT TOP&lt;/font&gt;(100) PERCENT * &lt;font color="#000080"&gt;FROM&lt;/font&gt; Sales.Customer&lt;br&gt;&lt;font color="#000080"&gt;ORDER BY&lt;/font&gt; TerritoryID &lt;br&gt;GO&lt;br&gt;&lt;font color="#000080"&gt;SELECT&lt;/font&gt; * &lt;font color="#000080"&gt;FROM&lt;/font&gt; customersOrderedbyTerritory&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;You will notice that SELECTing from this view returns&amp;nbsp; a result set 'ignorant' of the ORDER BY directive. In essence, the optimizer ignores the TOP and ORDER BY clauses.&amp;nbsp; To achieve the desired result, there is a &lt;a href="http://support.microsoft.com/default.aspx/kb/926292" target="_blank"&gt;hot fix available from MSFT&lt;/a&gt; which introduces &lt;strong&gt;trace flag 168&lt;/strong&gt; and also requires you set the database compatibility level to 80 (SQL Server 2000).&lt;/p&gt; &lt;p&gt;Apparently, the problem also extends to Common Table Expressions (CTE) which use the same constructs such as :&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font color="#000080"&gt;WITH&lt;/font&gt; territorialcustomers &lt;font color="#000080"&gt;AS&lt;/font&gt;&lt;br&gt;(&lt;br&gt;&lt;font color="#000080"&gt;SELECT TOP&lt;/font&gt;(100) PERCENT * &lt;font color="#000080"&gt;FROM&lt;/font&gt; Sales.Customer&lt;br&gt;&lt;font color="#000080"&gt;ORDER BY&lt;/font&gt; TerritoryID &lt;br&gt;)&lt;br&gt;&lt;font color="#000080"&gt;SELECT&lt;/font&gt; * &lt;font color="#000080"&gt;FROM&lt;/font&gt; territorialcustomers&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;If you don't want to set your compatibility level to 80, you can use &lt;strong&gt;TOP (99.999999999999)&lt;/strong&gt; instead. This somehow fools the optimizer to sort the data the way you want it to. Of course, it is only useful if your table contains less than 10 million records since the 0.000000000001% difference may start to show.&lt;/p&gt; &lt;p&gt;Well, if you insist on using the view, you can avoid the hot fix by using the ORDER BY clause in a table-valued function to retrieve your ordered data .&amp;nbsp; You can then wrap your view around this UDF. &lt;/p&gt; &lt;p&gt;I have not checked if this behavior has been carried forward to SQL Server 2008.&lt;/p&gt;&lt;img src="http://blogs.geekdojo.net/aggbug.aspx?PostID=2022290945" width="1" height="1"&gt;</description></item><item><title>Lessons From The Trenches</title><link>http://blogs.geekdojo.net/nathan/archive/2008/08/04/2022290944.aspx</link><pubDate>Tue, 05 Aug 2008 06:08:01 GMT</pubDate><guid isPermaLink="false">8c778905-0e18-4c86-9fd6-6e26bc083633:2022290944</guid><dc:creator>nathan</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.geekdojo.net/nathan/comments/2022290944.aspx</comments><wfw:commentRss>http://blogs.geekdojo.net/nathan/commentrss.aspx?PostID=2022290944</wfw:commentRss><wfw:comment>http://blogs.geekdojo.net/rsscomments/2022290944.aspx</wfw:comment><description>&lt;p&gt;A substantial part of my development career was spent on the assembly line churning out code based on someone else specifications. There was always somebody else to handle the financial, administrative, marketing and sales aspects of&amp;nbsp; the whole manufacturing process - what I used to call the 'social' face of software. Now that I am running my own small software outfit and having gone through a few projects, the lessons seem to be coming my way fast and hard on a daily basis. Most of them are the 'social' kind and I will proceed to randomly throw them at you, mainly because I don't want to forget them. &lt;/p&gt; &lt;ol&gt; &lt;li&gt;Document all proposed requirements (features) to the most atomic level of detail possible. Ambiguous or general statements can fool you into optimism as far as the project timeline and budget is concerned. A specification statement like "&lt;em&gt;The new system should allow employees to view their own data currently stored in the HR management system oracle database&lt;/em&gt;" cannot be the basis of a design. Break it down with questions like this:  &lt;ul&gt; &lt;li&gt;&lt;em&gt;&lt;strong&gt;Allow&lt;/strong&gt;&lt;/em&gt; - May suggest security concerns. Will this be integrated security (implicit) or forms-based (explicit)?. Is there some form of identity management in place? Will we have to log (keep track) access to the system somewhere?  &lt;li&gt;&lt;em&gt;&lt;strong&gt;Employees&lt;/strong&gt;&lt;/em&gt; - How many? Where are they located? Will each computer need some form of installation or setup procedure before using the system?  &lt;li&gt;&lt;em&gt;&lt;strong&gt;View&lt;/strong&gt;&lt;/em&gt; - Where is the viewpoint? i.e. can the employee view the data while outside the LAN. What will they use to view the data? i.e a browser, a Windows forms application through a VPN? Do we need to encrypt the data? What obstacles lie between the user and the data? Firewalls,  &lt;li&gt;&lt;em&gt;&lt;strong&gt;Own&lt;/strong&gt;&lt;/em&gt; - Are there people who can view other peoples' data? Who manages all these permissions?  &lt;li&gt;&lt;em&gt;&lt;strong&gt;Data&lt;/strong&gt;&lt;/em&gt; - Which data exactly? i.e. Salaries, leave (vacation), loans, employment history (vertical and horizontal movement within the firm). How should each be displayed?  &lt;li&gt;&lt;strong&gt;Oracle&lt;/strong&gt; - Which version? Oracle client software installation? Who is responsible for this other database? Will they help with scripts to get the data out? Will we be allowed access to some of the data during development? &lt;em&gt;Silently:(Do we have skills to deal with PL/SQL and ADO.NET&lt;/em&gt;?). Any documentation available?  &lt;li&gt;If most of the above questions can be answered satisfactorily by the client, you may be able to do a better estimate than just a '1 man-week' guess. In fact, you might realize that this could very easily end up at slightly more than '1 man-month'. Remember that I am talking about one requirements specification statement.&amp;nbsp;&amp;nbsp; &lt;li&gt;You might, of course, want to wear the 'architects' hat and start thinking of &lt;em&gt;performance, availability, scalability, extensibility and interoperability&lt;/em&gt; at the statement level. These thoughts will not reduce the value of your requirements and may uncover other concerns and wishes not previously stated.&lt;/li&gt;&lt;/ul&gt; &lt;li&gt;Communicate anything involving an agreed or suggested flux in resources and system features in writing (e-mail) as much as possible. Copy (cc) the communication to all the people relevant to that part of the project. After meetings, e-mail the client highlighting the main points agreed or disagreed during that meeting and ask for confirmation. You may look dumb and slow but this will cover your bases and avoid any ambiguity or disputes later.  &lt;li&gt;Perform user acceptance testing as early as sanely possible. Unit and functional tests can be greatly complemented by the almost natural ability of a user to always crash a system. The fact that the software is incomplete only serves to gauge your feature prioritization skills. This could be a better indicator of where the project status instead of just checking off a feature list in a garage or on an Ms Project gantt chart. In any case, a client nod is worth more than any test case scenarios you can cook up.&amp;nbsp; &lt;li&gt;Demarcate or at least try to understand the boundary between the &lt;em&gt;user &lt;/em&gt;and the&lt;em&gt; client&lt;/em&gt;. These two entities are important to the closure of the project. The client will pay for the software. Users will use your software as often as necessary. Users will certify your system. The client may not pay if the user is not happy. Your will be supporting users later - despite what the contract says. When the client is the user, you may have an easier job navigating through the acceptance and invoicing phases. If they are not , get a good project liaison to grease the path between them.  &lt;li&gt;Listen to all levels of the user spectrum. Every data entry and retrieval scenario should have a 'persona' and a real blood-and-bones user early in the project. Different people have different views of design. You may be able to merge these different views with your own or even learn something new. Not listening creates room for assumptions. Assumptions can spawn undefined elasticity in resources and features. Listening later only serves to widen the delicate gap between project initiation and final invoicing.  &lt;li&gt;Know the accounting practices and procedures of the client. What they may consider fast payment processing may be too slow for you. Your bills and obligations may not dance to the same tune as your clients' workflow and traditions. This will also allow you to plan for cash flow.&amp;nbsp;&amp;nbsp; &lt;li&gt;If you can, start creating user documentation (help files) early. Consider this as a validation of the requirements and testing activities. This also brings the end game nearer.  &lt;li&gt;If there is a training clause in the contract, make sure the scope is clear. You may find yourself teaching PC skills, database administration, active directory services or even VB.NET for free or at a lower price than you would have if it was stated clearly from the beginning.  &lt;li&gt;If you can help it, get somebody who knows their way around the establishment and has a goodwill for the project as a liaison. Canceled or missed appointments with various people, internal events or staff deployment changes in the client firm can affect your ship date. You may also need help bullying the accounts people - they usually respond better to internal pressure and nagging. A good rapport with the internal IT team can be good for repeat or referential business. It might just help to reduce your medical bills as you struggle to deploy your new software.  &lt;li&gt;It may be that you got the job through a competitive process (a.k.a tender). Make sure you get to know why you won/lost the bid and what your competition had to offer in their technical and financial proposals. There will always be a next time and it is very likely that you will meet your competitors again. Such knowledge can only serve to improve your chances.&amp;nbsp; &lt;li&gt;In case you were wondering, I have little to say about software maintenance contracts. You will not need to do much if the agreement (SLA) is clear and your software approximates the elusive zero-bug state. On the other hand, it is very easy to spend all your money 'maintaining' the software as you respond to every user SOS and hunt down all kinds of bugs.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Whether my experiences are out of place is subject to the test of time and the pressure of future projects. In the meantime, they will serve as a reminder that the world is still interesting outside the confines of Visual Studio and the SQL Server query editor.&lt;/p&gt;&lt;img src="http://blogs.geekdojo.net/aggbug.aspx?PostID=2022290944" width="1" height="1"&gt;</description></item><item><title>Free Download of Refactor! For ASP.NET 2.0</title><link>http://blogs.geekdojo.net/nathan/archive/2007/02/03/109525.aspx</link><pubDate>Sun, 04 Feb 2007 03:59:00 GMT</pubDate><guid isPermaLink="false">8c778905-0e18-4c86-9fd6-6e26bc083633:109525</guid><dc:creator>nathan</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.geekdojo.net/nathan/comments/109525.aspx</comments><wfw:commentRss>http://blogs.geekdojo.net/nathan/commentrss.aspx?PostID=109525</wfw:commentRss><wfw:comment>http://blogs.geekdojo.net/rsscomments/109525.aspx</wfw:comment><description>&lt;P&gt;Mark Miller (DevExpress)&amp;nbsp;is offering a &lt;A href="http://www.devexpress.com/refactorasp" target=_blank&gt;free for all download of Refactor! for Visual Studio 2005&lt;/A&gt;. It includes &lt;STRONG&gt;25 refactorings&lt;/STRONG&gt;, nine of which are dedicated to ASP.NET development (the other 16 work in VB and C# code-behind files). There is also a&amp;nbsp;full-screen&amp;nbsp;&lt;A href="http://www.devexpress.com/Products/NET/IDETools/RefactorASP/Presentation/Refactor_for_ASP_NET_Full/" target=_blank&gt;training video&lt;/A&gt; available for your viewing pleasure.Having used&amp;nbsp;the Pro&amp;nbsp;version of the tool for some time now, I am happy to see that Mark has decided to make&amp;nbsp;some of the features free for&amp;nbsp;public consumption. The features that are available while working with ASP.NET 2.0 are:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&amp;nbsp;Add Validator 
&lt;LI&gt;Extract ContentPlaceHolder 
&lt;LI&gt;Extract ContentPlaceHolder (and create master page) 
&lt;LI&gt;Extract Style (Class) : &lt;EM&gt;Not available inside content pages&lt;/EM&gt; 
&lt;LI&gt;Extract Style (id) : &lt;EM&gt;Not available inside content pages&lt;/EM&gt; 
&lt;LI&gt;Move to Code-behind 
&lt;LI&gt;Move Style Attributes to CSS 
&lt;LI&gt;Rename Style 
&lt;LI&gt;Surround with Update Panel: &lt;EM&gt;Does not modify the Web.Config file&lt;/EM&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;img src="http://blogs.geekdojo.net/aggbug.aspx?PostID=109525" width="1" height="1"&gt;</description></item><item><title>T-SQL Wordiness</title><link>http://blogs.geekdojo.net/nathan/archive/2006/11/03/26434.aspx</link><pubDate>Fri, 03 Nov 2006 09:02:44 GMT</pubDate><guid isPermaLink="false">8c778905-0e18-4c86-9fd6-6e26bc083633:26434</guid><dc:creator>nathan</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.geekdojo.net/nathan/comments/26434.aspx</comments><wfw:commentRss>http://blogs.geekdojo.net/nathan/commentrss.aspx?PostID=26434</wfw:commentRss><wfw:comment>http://blogs.geekdojo.net/rsscomments/26434.aspx</wfw:comment><description>&lt;p&gt;T-SQL may not be a 'true' programming language but it sure has lots of language features that make&amp;nbsp;manipulating data possible. I spend quite a reasonable amount of time writing T-SQL scripts; either&amp;nbsp;in production or learning or sometimes while teaching. While doing this I have often found myself cursing at the amount of typing required to accomplish otherwise simple constructs. Here is a sampling what I am rambling about:&lt;/p&gt; &lt;p&gt;1. Separation of variable declaration and initialization. Put simply, I would love to be able to do the following, at least for scalar &amp;nbsp;types&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font color="#0080ff"&gt;&lt;/font&gt;&lt;strong&gt;&lt;font color="#0000ff"&gt;DECLARE&lt;/font&gt; @var int=0&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;instead of having to do it over two lines, thus&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;DECLARE @var int&lt;br&gt;SET @var=0&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;2.&amp;nbsp;Creating database objects using&amp;nbsp;IF ..DROP..CREATE. It is just involves too many keystrokes. Oracle PL/SQL has the CREATE OR REPLACE syntax. Why wouldn't the SQL Server team indulge us on this one? For those who are wondering what this is all about, if you want to&amp;nbsp;create a table,&amp;nbsp;&amp;nbsp;you must check if it exists before issuing the CREATE statement. You could go about it like this&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;IF OBJECT_ID('myTable') IS NOT NULL&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DROP TABLE myTable&lt;br&gt;CREATE TABLE myTable(col1 int)&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Please, just&amp;nbsp;give us this instead&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;strong&gt;&lt;font color="#0000ff"&gt;CREATE&lt;/font&gt; OR &lt;font color="#0000ff"&gt;REPLACE&lt;/font&gt; TABLE myTable(col1 int)&lt;/strong&gt; &lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;If I am not mistaken, somebody has already asked for this on the &lt;a href="https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=127219" target="_blank"&gt;Microsoft Connect&lt;/a&gt; site. You&amp;nbsp;may want to&amp;nbsp;vote for that feature.&lt;/p&gt; &lt;p&gt;3. Is there any hope for a more compact loop construct instead of this?&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;DECLARE @var int&lt;br&gt;SET @var=0&lt;br&gt;WHILE @var&amp;lt;1000&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; BEGIN&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SET @var=@var+1&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; --Some code here&lt;br&gt;&amp;nbsp;&amp;nbsp; END&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;You notice that the six uncommented lines are required to do a simple loop. This can quickly increase if you have more than one loop&amp;nbsp;(a.k.a an&amp;nbsp;'inner'&amp;nbsp;loop). Since I don't expect to see curly brackets in T-SQL anytime soon, what about a &lt;strong&gt;FOR...NEXT&lt;/strong&gt; simple VB-like loop?&lt;/p&gt; &lt;p&gt;I may come off as a truly lazy DBA, but after&amp;nbsp;exposure to other 'programming' languages, I feel that once in a while my productivity is impaired with this chatful state of affairs. I am not sure if there is anything in the ANSI-SQL standard that prohibits these wishes from coming true, but I am definitely sure that the SQL Server programmability team should think about it.&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Note To Self&lt;/strong&gt;:&amp;nbsp;If wishes were horses, beggars would surely ride.&lt;/p&gt;&lt;img src="http://blogs.geekdojo.net/aggbug.aspx?PostID=26434" width="1" height="1"&gt;</description></item><item><title>July Refresh of Books Online</title><link>http://blogs.geekdojo.net/nathan/archive/2006/07/22/11578.aspx</link><pubDate>Sun, 23 Jul 2006 00:49:00 GMT</pubDate><guid isPermaLink="false">8c778905-0e18-4c86-9fd6-6e26bc083633:11578</guid><dc:creator>nathan</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.geekdojo.net/nathan/comments/11578.aspx</comments><wfw:commentRss>http://blogs.geekdojo.net/nathan/commentrss.aspx?PostID=11578</wfw:commentRss><wfw:comment>http://blogs.geekdojo.net/rsscomments/11578.aspx</wfw:comment><description>The July Refresh of the SQL Server Books Online is now available. This&amp;nbsp;edition of the documentation is supposed to cater for all current editions of SQL Server including Express. &lt;A href="http://www.microsoft.com/technet/prodtechnol/sql/2005/downloads/books.mspx"&gt;Download&lt;/A&gt;&lt;img src="http://blogs.geekdojo.net/aggbug.aspx?PostID=11578" width="1" height="1"&gt;</description></item><item><title>Office 2007 Beta 2 </title><link>http://blogs.geekdojo.net/nathan/archive/2006/05/24/10946.aspx</link><pubDate>Thu, 25 May 2006 02:20:00 GMT</pubDate><guid isPermaLink="false">8c778905-0e18-4c86-9fd6-6e26bc083633:10946</guid><dc:creator>nathan</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.geekdojo.net/nathan/comments/10946.aspx</comments><wfw:commentRss>http://blogs.geekdojo.net/nathan/commentrss.aspx?PostID=10946</wfw:commentRss><wfw:comment>http://blogs.geekdojo.net/rsscomments/10946.aspx</wfw:comment><description>The public release of Office 2007 Beta 2 is now available. &lt;A href="http://www.microsoft.com/office/preview/beta/download/en/default.mspx"&gt;Download&lt;/A&gt;&amp;nbsp;&lt;img src="http://blogs.geekdojo.net/aggbug.aspx?PostID=10946" width="1" height="1"&gt;</description></item><item><title>A login has got to do what a login can do</title><link>http://blogs.geekdojo.net/nathan/archive/2006/04/26/10724.aspx</link><pubDate>Thu, 27 Apr 2006 01:36:00 GMT</pubDate><guid isPermaLink="false">8c778905-0e18-4c86-9fd6-6e26bc083633:10724</guid><dc:creator>nathan</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.geekdojo.net/nathan/comments/10724.aspx</comments><wfw:commentRss>http://blogs.geekdojo.net/nathan/commentrss.aspx?PostID=10724</wfw:commentRss><wfw:comment>http://blogs.geekdojo.net/rsscomments/10724.aspx</wfw:comment><description>&lt;P&gt;As an SQL Server admin, there are times when the combination of many users, groups, roles, logins and the various permissions&amp;nbsp;that can be given to each to do stuff&amp;nbsp;on various&amp;nbsp;databases and objects within&amp;nbsp;your server may just be too confusing. Just like the previous sentence.&lt;/P&gt;
&lt;P&gt;One way of coming out of this mess unscarthed is to rigorously document every permission&amp;nbsp;granted to every login/group and keep track of it all. I know many people who don't. I don't either.&amp;nbsp;Since you basically can't do&amp;nbsp;much with SQL Server unless 'explicity' granted or 'implicitly' allowed by virtue of your membership in the public or other groups/roles, I am normally much more worried about what I have GRANTED my logins rather than what I have explicitly DENIED them. In other words, most people would love to know who CAN do stuff rather than who CANNOT do stuff. So what else&amp;nbsp;can you do about it? I wrote a script (stored procedure actually)&amp;nbsp;to show me all the stuff that a given user/login can do&amp;nbsp;within a&amp;nbsp;particular database and on its hosting server. Here we go.&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#0000ff size=2&gt;CREATE&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;PROC&lt;/FONT&gt;&lt;FONT size=2&gt; [dbo]&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;[loginperms] 
&lt;P&gt;
&lt;P&gt;@login &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;varchar&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT size=2&gt;128&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;) 
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;AS&lt;/P&gt;
&lt;P dir=ltr style="MARGIN-RIGHT: 0px"&gt;SET &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;NOCOUNT&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;ON &lt;/P&gt;
&lt;P&gt;
&lt;P&gt;IF&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;SELECT&lt;/FONT&gt;&lt;FONT size=2&gt; is_disabled &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;from&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;sys.server_principals&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;WHERE&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;name&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;@login&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;)=&lt;/FONT&gt;&lt;FONT size=2&gt;1 
&lt;P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;SELECT&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'The login &amp;lt;'&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;+&lt;/FONT&gt;&lt;FONT size=2&gt; @login &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;+&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'&amp;gt; is disabled' 
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;ELSE&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;SELECT&lt;/FONT&gt;&lt;FONT size=2&gt; [Object Class]&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;class_desc&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;, &lt;/FONT&gt;&lt;FONT size=2&gt;[Object]&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;CASE&lt;/FONT&gt;&lt;FONT size=2&gt; class &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;WHEN&lt;/FONT&gt;&lt;FONT size=2&gt; 100 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;THEN&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;@@SERVERNAME&lt;/FONT&gt;&lt;FONT size=2&gt; 
&lt;P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;WHEN&lt;/FONT&gt;&lt;FONT size=2&gt; 105 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;THEN&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;SELECT&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;name&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;FROM&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;sys.endpoints&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;WHERE&lt;/FONT&gt;&lt;FONT size=2&gt; endpoint_id&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;major_id&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;FONT size=2&gt; 
&lt;P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;ELSE&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;object_name&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT size=2&gt;major_id&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;END&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt;[column]&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;''&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt;[Permission]&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;permission_name&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;, 
&lt;P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;[Permission Type]&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;CASE&lt;/FONT&gt;&lt;FONT size=2&gt; spr&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;type&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;WHEN&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'U'&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;THEN&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'Direct'&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;WHEN&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'R'&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;THEN&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'Inherited'&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;END&lt;/FONT&gt;&lt;FONT size=2&gt; 
&lt;P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;FROM&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;sys.server_permissions&lt;/FONT&gt;&lt;FONT size=2&gt; spm &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;JOIN&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;sys.server_principals&lt;/FONT&gt;&lt;FONT size=2&gt; spr 
&lt;P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;ON&lt;/FONT&gt;&lt;FONT size=2&gt; spm&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;grantee_principal_id&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;spr&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;principal_id 
&lt;P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;WHERE&lt;/FONT&gt;&lt;FONT size=2&gt; spr&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;type&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;NOT&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;IN(&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'C'&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;AND&lt;/FONT&gt;&lt;FONT size=2&gt; is_disabled&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;0 &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;AND&lt;/FONT&gt;&lt;FONT size=2&gt; spr&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;name&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;@login 
&lt;P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;UNION 
&lt;P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;SELECT&lt;/FONT&gt;&lt;FONT size=2&gt; [Object Class]&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;class_desc&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt;Object&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;CASE&lt;/FONT&gt;&lt;FONT size=2&gt; class &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;WHEN&lt;/FONT&gt;&lt;FONT size=2&gt; 100 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;THEN&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;@@SERVERNAME&lt;/FONT&gt;&lt;FONT size=2&gt; 
&lt;P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;WHEN&lt;/FONT&gt;&lt;FONT size=2&gt; 105 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;THEN&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;SELECT&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;name&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;FROM&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;sys.endpoints&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;WHERE&lt;/FONT&gt;&lt;FONT size=2&gt; endpoint_id&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;major_id&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;FONT size=2&gt; 
&lt;P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;ELSE&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;object_name&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT size=2&gt;major_id&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;END&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;''&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt;permission_name&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;, 
&lt;P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;[Permission Type]&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;CASE&lt;/FONT&gt;&lt;FONT size=2&gt; spr&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;type&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;WHEN&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'U'&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;THEN&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'Direct'&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;WHEN&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'R'&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;THEN&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'Inherited'&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;END&lt;/FONT&gt;&lt;FONT size=2&gt; 
&lt;P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;FROM&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;sys.server_permissions&lt;/FONT&gt;&lt;FONT size=2&gt; spm &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;JOIN&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;sys.server_principals&lt;/FONT&gt;&lt;FONT size=2&gt; spr 
&lt;P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;ON&lt;/FONT&gt;&lt;FONT size=2&gt; spm&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;grantee_principal_id&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;spr&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;principal_id 
&lt;P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;WHERE&lt;/FONT&gt;&lt;FONT size=2&gt; spr&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;type&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;NOT&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;IN(&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'C'&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;AND&lt;/FONT&gt;&lt;FONT size=2&gt; is_disabled&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;0 &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;AND&lt;/FONT&gt;&lt;FONT size=2&gt; spr&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;name&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'public'&lt;/FONT&gt;&lt;FONT size=2&gt; 
&lt;P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;UNION 
&lt;P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;SELECT&lt;/FONT&gt;&lt;FONT size=2&gt; [Object Class]&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;CASE&lt;/FONT&gt;&lt;FONT size=2&gt; class &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;WHEN&lt;/FONT&gt;&lt;FONT size=2&gt; 1 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;THEN&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;SELECT&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;REPLACE&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT size=2&gt;type_desc&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'_'&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;' '&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;FROM&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;sys.all_objects&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;WHERE&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;object_id&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;major_id&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;ELSE&lt;/FONT&gt;&lt;FONT size=2&gt; class_desc &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;END&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;, 
&lt;P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;Object &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;CASE&lt;/FONT&gt;&lt;FONT size=2&gt; class &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;WHEN&lt;/FONT&gt;&lt;FONT size=2&gt; 0 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;THEN&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;DB_NAME&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;()&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;ELSE&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;object_name&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT size=2&gt;major_id&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;END&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;, &lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;[Column]&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;CASE&lt;/FONT&gt;&lt;FONT size=2&gt; minor_id &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;WHEN&lt;/FONT&gt;&lt;FONT size=2&gt; 0 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;then&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;''&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;ELSE&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;COL_NAME&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT size=2&gt;major_id&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt;minor_id&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;END&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt;permission_name&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;, 
&lt;P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;[Permission Type]&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;CASE&lt;/FONT&gt;&lt;FONT size=2&gt; dpri&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;type&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;WHEN&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'U'&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;THEN&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'Direct'&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;WHEN&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'R'&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;THEN&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'Inherited'&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;END&lt;/FONT&gt;&lt;FONT size=2&gt; 
&lt;P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;FROM&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;sys.database_permissions&lt;/FONT&gt;&lt;FONT size=2&gt; dperm &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;JOIN&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;sys.database_principals&lt;/FONT&gt;&lt;FONT size=2&gt; dpri 
&lt;P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;ON&lt;/FONT&gt;&lt;FONT size=2&gt; dperm&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;grantee_principal_id&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;dpri&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;principal_id 
&lt;P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;WHERE&lt;/FONT&gt;&lt;FONT size=2&gt; dpri&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;name&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;@login &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;AND&lt;/FONT&gt;&lt;FONT size=2&gt; state_desc &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;LIKE&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'G%'&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;AND&lt;/FONT&gt;&lt;FONT size=2&gt; major_id&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&amp;gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;0 
&lt;P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;UNION 
&lt;P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;SELECT&lt;/FONT&gt;&lt;FONT size=2&gt; [Object Class]&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;class_desc&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;, &lt;/FONT&gt;&lt;FONT size=2&gt;Object&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;CASE&lt;/FONT&gt;&lt;FONT size=2&gt; class &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;WHEN&lt;/FONT&gt;&lt;FONT size=2&gt; 0 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;THEN&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;DB_NAME&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;()&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;ELSE&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;object_name&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT size=2&gt;major_id&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;END&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;, 
&lt;P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;[Column]&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;CASE&lt;/FONT&gt;&lt;FONT size=2&gt; minor_id &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;WHEN&lt;/FONT&gt;&lt;FONT size=2&gt; 0 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;then&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;''&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;ELSE&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;COL_NAME&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;FONT size=2&gt;major_id&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt;minor_id&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;END&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;, &lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;permission_name&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;FONT size=2&gt;[Permission Type]&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;CASE&lt;/FONT&gt;&lt;FONT size=2&gt; dpri&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;type&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;WHEN&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'U'&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;THEN&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'Direct'&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;WHEN&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'R'&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;THEN&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'Inherited'&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;END&lt;/FONT&gt;&lt;FONT size=2&gt; 
&lt;P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;FROM&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;sys.database_permissions&lt;/FONT&gt;&lt;FONT size=2&gt; dperm &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;JOIN&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;sys.database_principals&lt;/FONT&gt;&lt;FONT size=2&gt; dpri 
&lt;P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;ON&lt;/FONT&gt;&lt;FONT size=2&gt; dperm&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;grantee_principal_id&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;dpri&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;principal_id 
&lt;P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;WHERE&lt;/FONT&gt;&lt;FONT size=2&gt; dpri&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;name&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'public'&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;AND&lt;/FONT&gt;&lt;FONT size=2&gt; state_desc &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;LIKE&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;'G%'&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;AND&lt;/FONT&gt;&lt;FONT size=2&gt; major_id&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&amp;gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;0 
&lt;P&gt;
&lt;P&gt;GO&lt;/P&gt;&lt;/FONT&gt;
&lt;P&gt;You may want to use the&amp;nbsp;procedure like this:&lt;/P&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;EXECUTE&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;nbsp;&lt;/FONT&gt;&lt;FONT size=2&gt;[dbo]&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;[loginperms] &lt;FONT color=#ff0000&gt;'DOMAIN\user'&lt;/FONT&gt;&lt;/FONT&gt; 
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;or&lt;/P&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;EXECUTE&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;nbsp;&lt;/FONT&gt;&lt;FONT size=2&gt;[dbo]&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;[loginperms] &lt;FONT color=#ff0000&gt;'sql_login'&lt;/FONT&gt; 
&lt;P&gt;
&lt;P&gt;&lt;/FONT&gt;
&lt;P&gt;
&lt;P&gt;I know, it is even easier&amp;nbsp;get this information using the brand new SQL Server Management Objects (SMO).&amp;nbsp;Maybe I will blog about that on another day. In the meantime, let's just be happy with T-SQL.&lt;/P&gt;&lt;img src="http://blogs.geekdojo.net/aggbug.aspx?PostID=10724" width="1" height="1"&gt;</description><category domain="http://blogs.geekdojo.net/nathan/archive/category/126.aspx">Technical</category></item><item><title>SQL Server 2005 Books Online April Refresh</title><link>http://blogs.geekdojo.net/nathan/archive/2006/04/24/10674.aspx</link><pubDate>Tue, 25 Apr 2006 01:26:00 GMT</pubDate><guid isPermaLink="false">8c778905-0e18-4c86-9fd6-6e26bc083633:10674</guid><dc:creator>nathan</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.geekdojo.net/nathan/comments/10674.aspx</comments><wfw:commentRss>http://blogs.geekdojo.net/nathan/commentrss.aspx?PostID=10674</wfw:commentRss><wfw:comment>http://blogs.geekdojo.net/rsscomments/10674.aspx</wfw:comment><description>&lt;P&gt;The delayed SQL Server 2005 Books Online (BOL) April 2006 refresh should now be up and ready for downloading. &lt;/P&gt;
&lt;P&gt;Get it &lt;A href="http://www.microsoft.com/downloads/details.aspx?FamilyID=be6a2c5d-00df-4220-b133-29c1e0b6585f&amp;amp;DisplayLang=en"&gt;here&lt;/A&gt;&lt;/P&gt;&lt;img src="http://blogs.geekdojo.net/aggbug.aspx?PostID=10674" width="1" height="1"&gt;</description><category domain="http://blogs.geekdojo.net/nathan/archive/category/125.aspx">What's going On</category></item><item><title>Mobile and Embedded Devcon (MEDC) 2006 Europe</title><link>http://blogs.geekdojo.net/nathan/archive/2006/04/13/10553.aspx</link><pubDate>Fri, 14 Apr 2006 03:37:00 GMT</pubDate><guid isPermaLink="false">8c778905-0e18-4c86-9fd6-6e26bc083633:10553</guid><dc:creator>nathan</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.geekdojo.net/nathan/comments/10553.aspx</comments><wfw:commentRss>http://blogs.geekdojo.net/nathan/commentrss.aspx?PostID=10553</wfw:commentRss><wfw:comment>http://blogs.geekdojo.net/rsscomments/10553.aspx</wfw:comment><description>&lt;P&gt;&lt;STRONG&gt;&lt;A href="http://www.microsoft.com/europe/medc/"&gt;&lt;IMG src="http://www.microsoft.com/europe/medc/images/banners/468x60_V1.gif" border=0&gt;&lt;/A&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Details&lt;/STRONG&gt;:&lt;BR&gt;&lt;BR&gt;&lt;STRONG&gt;Event&lt;/STRONG&gt;: Mobile and Embedded Devcon (MEDC) 2006 Europe&lt;BR&gt;&lt;BR&gt;&lt;STRONG&gt;Dates&lt;/STRONG&gt;: 6th-8th June 2006&lt;BR&gt;&lt;BR&gt;&lt;STRONG&gt;Place&lt;/STRONG&gt;: Nice, France&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Sessions:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Using Microsoft Windows Embedded Products to Bring to Market a Broad Range of Devices &lt;/LI&gt;
&lt;LI&gt;Windows CE Overview &lt;/LI&gt;
&lt;LI&gt;What's New in the Next Version of Windows CE Tools&lt;/LI&gt;
&lt;LI&gt;Writing Windows CE Services &lt;/LI&gt;
&lt;LI&gt;Stabilizing the Platform &lt;/LI&gt;
&lt;LI&gt;Inside the Windows CE Kernel &lt;/LI&gt;
&lt;LI&gt;Windows CE Memory Tools for Native Code &lt;/LI&gt;
&lt;LI&gt;Windows CE Performance Tools &amp;amp; Techniques&lt;/LI&gt;
&lt;LI&gt;How to write a Windows CE Boot Loader (combine with Secure Bootloader) &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Discounts are available&amp;nbsp;if you&amp;nbsp;register before the end of next week. Get more details at&amp;nbsp; &lt;A href="http://www.microsoft.com/europe/medc/"&gt;http://www.microsoft.com/europe/medc/&lt;/A&gt;&lt;BR&gt;&lt;/P&gt;&lt;img src="http://blogs.geekdojo.net/aggbug.aspx?PostID=10553" width="1" height="1"&gt;</description></item><item><title>Dubai DevCon</title><link>http://blogs.geekdojo.net/nathan/archive/2006/04/13/10551.aspx</link><pubDate>Fri, 14 Apr 2006 00:09:00 GMT</pubDate><guid isPermaLink="false">8c778905-0e18-4c86-9fd6-6e26bc083633:10551</guid><dc:creator>nathan</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.geekdojo.net/nathan/comments/10551.aspx</comments><wfw:commentRss>http://blogs.geekdojo.net/nathan/commentrss.aspx?PostID=10551</wfw:commentRss><wfw:comment>http://blogs.geekdojo.net/rsscomments/10551.aspx</wfw:comment><description>What are you doing on the Labour Day weekend?&amp;nbsp;&amp;nbsp;You can attend the First Developers Conference in Dubai and maybe&amp;nbsp;do some shopping while you are there.&amp;nbsp;There will be stuff on ASP.NET, Office 2007 and&amp;nbsp;Vista.&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;A href="http://www.microsoft.com/middleeast/UAE/developers/geeks/"&gt;Microsoft Middle East has put up the details on their website&lt;/A&gt;. Go and register.&lt;img src="http://blogs.geekdojo.net/aggbug.aspx?PostID=10551" width="1" height="1"&gt;</description></item><item><title>PostXing Beta</title><link>http://blogs.geekdojo.net/nathan/archive/2006/04/12/10536.aspx</link><pubDate>Thu, 13 Apr 2006 00:33:10 GMT</pubDate><guid isPermaLink="false">8c778905-0e18-4c86-9fd6-6e26bc083633:10536</guid><dc:creator>nathan</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.geekdojo.net/nathan/comments/10536.aspx</comments><wfw:commentRss>http://blogs.geekdojo.net/nathan/commentrss.aspx?PostID=10536</wfw:commentRss><wfw:comment>http://blogs.geekdojo.net/rsscomments/10536.aspx</wfw:comment><description>
&lt;p&gt;I just downloaded &lt;a href="http://www.chrisfrazier.net/blog"&gt;Chris 
Frazier's&lt;/a&gt; PostXing &lt;a href="http://www.projectdistributor.net/Projects/Project.aspx?projectId=12"&gt;Beta 
(2.0.6068.2)&lt;/a&gt; and I am using it post this offline. If you can read it, then 
it works and it rocks!&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I was totally unable to use IMHO Instant blogger despite Ryan Rinaldi's 
suggestions. This might just change the way I've been 
blogging.&lt;/p&gt;&lt;img src="http://blogs.geekdojo.net/aggbug.aspx?PostID=10536" width="1" height="1"&gt;</description></item></channel></rss>