<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Gaute's .net weblog - T-SQL</title>
    <link>http://gaute.amende.no/</link>
    <description>thoughts on programming and computer related stuff</description>
    <language>en-us</language>
    <copyright>gaute</copyright>
    <lastBuildDate>Mon, 08 Dec 2008 18:55:56 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.1.8102.813</generator>
    <managingEditor>gaute@amende.no</managingEditor>
    <webMaster>gaute@amende.no</webMaster>
    <item>
      <trackback:ping>http://gaute.amende.no/Trackback.aspx?guid=1068f7c7-3062-4a1b-9731-bb587163d213</trackback:ping>
      <pingback:server>http://gaute.amende.no/pingback.aspx</pingback:server>
      <pingback:target>http://gaute.amende.no/PermaLink,guid,1068f7c7-3062-4a1b-9731-bb587163d213.aspx</pingback:target>
      <dc:creator>Gaute Magnussen</dc:creator>
      <wfw:comment>http://gaute.amende.no/CommentView,guid,1068f7c7-3062-4a1b-9731-bb587163d213.aspx</wfw:comment>
      <wfw:commentRss>http://gaute.amende.no/SyndicationService.asmx/GetEntryCommentsRss?guid=1068f7c7-3062-4a1b-9731-bb587163d213</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">Last week I had to make a SQL Procedure
go faster and a new join in the same operation. From the execution plan I could see
that the thing that cost most time was a call to an external function made as a .NET
CLR that got all the groups a person was member of, and returned it as a comma separated
string. This tok a couple of milliseconds, each time, and with some of the users input
resulting in over 8000 calls in a single statement, the procedure took to long time.
I also had the requirement to add an other column in the result, showing a comma separated
list of functions each persons had. Doing this the same way as before, would turn
the procedure almost twice as sluggish as before.<br /><br />
To get the result wanted, a small trick was used. Here is a simplified version of
what I wrote:<br /><pre><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"></span><span style="color: Black; background-color: transparent; font-family: Courier New; font-size: 11px;"><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">SELECT</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">TOP</span> 10 <span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;">substring</span>(O.Functions,2,500) <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">FROM</span> dbo.Tp_Person
P <span style="color: Silver; background-color: transparent; font-family: Courier New; font-size: 11px;">CROSS</span> APPLY
( <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">SELECT</span><span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">','</span> + <span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;">CAST</span>(FunctionName <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">AS</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">varchar</span>) <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">AS</span> [<span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">text</span>()] <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">FROM</span> dbo.Tp_Function
F <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">WHERE</span> F.Personid
= P.Personid <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">FOR</span> XML
PATH(<span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">''</span>)
) O( Functions )</span><span style="color: Black; background-color: transparent; font-family: Courier New; font-size: 11px;"><br /><br /></span><br />
This trick actually reduced the time of the procedure on 5000 people from about 30
seconds to 1,5 seconds. Made my day. 
<br /></pre><p></p><img width="0" height="0" src="http://gaute.amende.no/aggbug.ashx?id=1068f7c7-3062-4a1b-9731-bb587163d213" /></body>
      <title>SQL to make a comma separated string from a resultset,</title>
      <guid isPermaLink="false">http://gaute.amende.no/PermaLink,guid,1068f7c7-3062-4a1b-9731-bb587163d213.aspx</guid>
      <link>http://gaute.amende.no/SQLToMakeACommaSeparatedStringFromAResultset.aspx</link>
      <pubDate>Mon, 08 Dec 2008 18:55:56 GMT</pubDate>
      <description>Last week I had to make a SQL Procedure go faster and a new join in the same operation. From the execution plan I could see that the thing that cost most time was a call to an external function made as a .NET CLR that got all the groups a person was member of, and returned it as a comma separated string. This tok a couple of milliseconds, each time, and with some of the users input resulting in over 8000 calls in a single statement, the procedure took to long time. I also had the requirement to add an other column in the result, showing a comma separated list of functions each persons had. Doing this the same way as before, would turn the procedure almost twice as sluggish as before.&lt;br&gt;
&lt;br&gt;
To get the result wanted, a small trick was used. Here is a simplified version of
what I wrote:&lt;br&gt;
&lt;pre&gt;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;&lt;/span&gt;&lt;span style="color: Black; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;SELECT&lt;/span&gt; &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;TOP&lt;/span&gt; 10 &lt;span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;substring&lt;/span&gt;(O.Functions,2,500) &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;FROM&lt;/span&gt; dbo.Tp_Person
P &lt;span style="color: Silver; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;CROSS&lt;/span&gt; APPLY
( &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;SELECT&lt;/span&gt; &lt;span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;','&lt;/span&gt; + &lt;span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;CAST&lt;/span&gt;(FunctionName &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;AS&lt;/span&gt; &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;varchar&lt;/span&gt;) &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;AS&lt;/span&gt; [&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;text&lt;/span&gt;()] &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;FROM&lt;/span&gt; dbo.Tp_Function
F &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;WHERE&lt;/span&gt; F.Personid
= P.Personid &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;FOR&lt;/span&gt; XML
PATH(&lt;span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;''&lt;/span&gt;)
) O( Functions )&lt;/span&gt;&lt;span style="color: Black; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;
&lt;br&gt;
&lt;br&gt;
&lt;/span&gt;
&lt;br&gt;
This trick actually reduced the time of the procedure on 5000 people from about 30
seconds to 1,5 seconds. Made my day. 
&lt;br&gt;
&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://gaute.amende.no/aggbug.ashx?id=1068f7c7-3062-4a1b-9731-bb587163d213" /&gt;</description>
      <comments>http://gaute.amende.no/CommentView,guid,1068f7c7-3062-4a1b-9731-bb587163d213.aspx</comments>
      <category>T-SQL</category>
    </item>
    <item>
      <trackback:ping>http://gaute.amende.no/Trackback.aspx?guid=930e8dc9-8c4f-471e-b272-98a26ed5c640</trackback:ping>
      <pingback:server>http://gaute.amende.no/pingback.aspx</pingback:server>
      <pingback:target>http://gaute.amende.no/PermaLink,guid,930e8dc9-8c4f-471e-b272-98a26ed5c640.aspx</pingback:target>
      <dc:creator>Gaute Magnussen</dc:creator>
      <wfw:comment>http://gaute.amende.no/CommentView,guid,930e8dc9-8c4f-471e-b272-98a26ed5c640.aspx</wfw:comment>
      <wfw:commentRss>http://gaute.amende.no/SyndicationService.asmx/GetEntryCommentsRss?guid=930e8dc9-8c4f-471e-b272-98a26ed5c640</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p style="margin: 0in; font-family: arial; font-size: 10pt; color: black;">
Checking if a email addresses is valid in SQL can be very convinient from time to
time. Here are two ways to do it in SQL, and a bit about them.
</p>
        <p style="margin: 0in; font-family: arial; font-size: 10pt; color: black;">
 
</p>
        <p style="margin: 0in; font-family: arial; font-size: 10pt; color: black;">
Here is a full SQL way to do this:
</p>
        <p style="margin: 0in; font-family: arial; font-size: 10pt; color: black;">
 
</p>
        <pre>
          <span style="color: Black; background-color: transparent; font-family: Courier New; font-size: 11px;">
            <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">Create</span>
            <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">function</span> VALIDEMAIL(@s <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">varchar</span>(255)) 
<br /><span style="color: Teal; background-color: transparent; font-family: Courier New; font-size: 11px;">--Returns
true if the string is a valid email address.</span><br />
returns <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">bit</span><br /><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">as</span><br /><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">BEGIN</span><br /><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">DECLARE</span> @u <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">VARCHAR</span>(60),
@v <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">VARCHAR</span>(60),
@x <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">VARCHAR</span>(60),
@i <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">int</span>,
@j <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">int</span>,
@result <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">bit</span><br /><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">SET</span> @result=1<br /><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">set</span> @s
= <span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;">rtrim</span>(<span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;">ltrim</span>(@s))<br /><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">SET</span> @i=<span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;">len</span>(@s)-<span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;">CHARINDEX</span>(<span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">'@'</span>,<span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;">reverse</span>(@s))+1<br /><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">if</span> @i
&lt;= 1 <span style="color: Silver; background-color: transparent; font-family: Courier New; font-size: 11px;">or</span><span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;">len</span>(@s)
&lt; 5<br /><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">begin</span><br />
  <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">set</span> @result
= 0<br />
  <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">goto</span> done<br /><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">end</span><br /><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">SET</span> @u=<span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;">LEFT</span>(@s,@i-1)<br /><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">SET</span> @j=<span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;">len</span>(@s)-<span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;">CHARINDEX</span>(<span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">'.'</span>,<span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;">reverse</span>(@s))+1<br /><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">SET</span> @v=<span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;">RIGHT</span>(@s,<span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;">LEN</span>(@s)-@j)<br /><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">if</span> @j
&lt; 3 <span style="color: Silver; background-color: transparent; font-family: Courier New; font-size: 11px;">or</span> @j
&lt; @i<br /><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">begin</span><br />
  <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">set</span> @result
= 0<br />
  <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">goto</span> done<br /><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">end</span><br /><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">SET</span> @x=<span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;">substring</span>(@s,@i+1,@j-@i-1)<br /><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">IF</span><span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;">LEN</span>(@x)&lt;2<br />
 <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">BEGIN</span><br />
 <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">SET</span> @result=0<br />
 <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">GOTo</span> done<br />
 <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">END</span><br /><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">IF</span> (<span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;">LEN</span>(@x)=3) <span style="color: Silver; background-color: transparent; font-family: Courier New; font-size: 11px;">AND</span> (@x <span style="color: Silver; background-color: transparent; font-family: Courier New; font-size: 11px;">NOT</span><span style="color: Silver; background-color: transparent; font-family: Courier New; font-size: 11px;">LIKE</span><span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">'[a-zA-Z][a-zA-Z][a-zA-Z]'</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">Collate</span> 
Latin1_General_BIN)<br />
 <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">BEGIN</span><br />
 <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">SET</span> @result=0<br />
 <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">GOTo</span> done<br />
 <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">END</span><br /><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">IF</span> (<span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;">LEN</span>(@x)=2) <span style="color: Silver; background-color: transparent; font-family: Courier New; font-size: 11px;">AND</span> (@x <span style="color: Silver; background-color: transparent; font-family: Courier New; font-size: 11px;">NOT</span><span style="color: Silver; background-color: transparent; font-family: Courier New; font-size: 11px;">LIKE</span><span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">'[a-zA-Z][a-zA-Z]'</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">Collate</span> 
Latin1_General_BIN)<br />
 <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">BEGIN</span><br />
 <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">SET</span> @result=0<br />
 <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">GOTo</span> done<br />
 <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">END</span><br /><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">SET</span> @i=1<br /><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">WHILE</span> (@i&lt;<span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;">LEN</span>(@u))<br />
 <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">BEGIN</span><br />
 <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">IF</span><span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;">SUBSTRING</span>(@u,@i,1) <span style="color: Silver; background-color: transparent; font-family: Courier New; font-size: 11px;">NOT</span><span style="color: Silver; background-color: transparent; font-family: Courier New; font-size: 11px;">LIKE</span><span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">'[a-zA-Z0-9_\-.+=/!#$&amp;''*%?^`{|}"@\\
]'</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">escape</span><span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">'\'</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">Collate</span> 
Latin1_General_BIN<br />
  <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">BEGIN</span><br />
  <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">SET</span> @result=0<br />
  <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">GOTo</span> done<br />
  <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">END</span><br />
 <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">SET</span> @i=@i+1<br />
 <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">END</span><br /><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">SET</span> @i=1<br /><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">WHILE</span> (@i&lt;<span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;">LEN</span>(@v))<br />
 <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">BEGIN</span><br />
 <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">IF</span><span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;">SUBSTRING</span>(@v,@i,1) <span style="color: Silver; background-color: transparent; font-family: Courier New; font-size: 11px;">NOT</span><span style="color: Silver; background-color: transparent; font-family: Courier New; font-size: 11px;">LIKE</span><span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">'[a-zA-Z]'</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">Collate</span> Latin1_General_BIN<br />
  <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">BEGIN</span><br />
  <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">SET</span> @result=0<br />
  <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">GOTo</span> done<br />
  <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">END</span><br />
 <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">SET</span> @i=@i+1<br />
 <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">END</span><br /><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">SET</span> @i=1<br /><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">WHILE</span> (@i&lt;<span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;">LEN</span>(@x))<br />
 <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">BEGIN</span><br />
 <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">IF</span><span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;">SUBSTRING</span>(@x,@i,1) <span style="color: Silver; background-color: transparent; font-family: Courier New; font-size: 11px;">NOT</span><span style="color: Silver; background-color: transparent; font-family: Courier New; font-size: 11px;">LIKE</span> N<span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">'[a-zA-Z\-.0-9]'</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">escape</span><span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">'\'</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">Collate</span> 
Latin1_General_BIN<br />
  <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">BEGIN</span><br />
  <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">SET</span> @result=0<br />
     <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">goto</span> done<br />
  <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">END</span><br />
 <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">SET</span> @i=@i+1<br />
 <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">END</span><br />
done:<br /><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">return</span> @result<br /><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">END</span><br />
GO<br /></span>
        </pre>
        <p style="margin: 0in; font-family: arial; font-size: 10pt; color: black;">
        </p>
        <p style="margin: 0in; font-family: Calibri; font-size: 11pt;" lang="en-US">
Here is another way, where you insert .NET CLR code in the database. Here I use the
.NET RegEx.Ismatch, so I can use it for tons of other stuff as well with the right
input.<br /></p>
        <p style="margin: 0in; font-family: Calibri; font-size: 11pt;" lang="en-US">
        </p>
        <pre>
          <span style="color: Black; background-color: transparent; font-family: Courier New; font-size: 11px;">
            <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">using</span> System; <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">using</span> System.Collections.Generic; <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">using</span> System.Text; <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">using</span> Microsoft.SqlServer.Server; <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">using</span> System.Data.SqlTypes; <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">using</span> System.Text.RegularExpressions; <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">namespace</span> SQLSignature
{ <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">public</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">class</span> SqlFunctions
{ [SqlFunction(IsDeterministic <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">true</span>,
DataAccess <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span> DataAccessKind.None)] <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">public</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">static</span> SqlBoolean
fn_RegexIsMatch(SqlString input, SqlString pattern) { <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">return</span> (SqlBoolean)Regex.IsMatch(input.Value,
pattern.Value); } } } </span>
        </pre>In SQL: 
<br /><pre><span style="color: Black; background-color: transparent; font-family: Courier New; font-size: 11px;"><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">CREATE</span> ASSEMBLY
SQLSignature <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">FROM</span><span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">'C:\CLR
Assemblies\Performance\SQLFunctions\bin\SQLFunctions.dll'</span>; GO <span style="color: Teal; background-color: transparent; font-family: Courier New; font-size: 11px;">--
Create fn_SQLSigCLR and fn_RegexReplace functions</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">CREATE</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">FUNCTION</span> dbo.fn_RegexIsMatch(@input <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">AS</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">NVARCHAR</span>(<span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;">MAX</span>),@pattern <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">AS</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">NVARCHAR</span>(<span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;">MAX</span>))RETURNS <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">BIT</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">WITH</span> RETURNS <span style="color: Silver; background-color: transparent; font-family: Courier New; font-size: 11px;">NULL</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">ON</span><span style="color: Silver; background-color: transparent; font-family: Courier New; font-size: 11px;">NULL</span> INPUT
EXTERNAL NAME SQLSignature.SQLFunctions.fn_RegexIsMatch; GO </span></pre>This can
be run with a command like:<br /><br /><pre><span style="color: Black; background-color: transparent; font-family: Courier New; font-size: 11px;">    <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">select</span> *
    <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">from</span> [AW].[person].emailaddress <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">as</span> p
    <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">where</span> dbo.fn_RegexIsMatch(<span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;">RTRIM</span>(<span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;">LTRIM</span>(<span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;">lower</span>(P.emailaddress))),<br /><span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;"> '^[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$'</span>)=1 </span></pre><br /><p style="margin: 0in; font-family: Calibri; font-size: 11pt;" lang="en-US">
I did some timings on the two functions and as you can see below there are big differences.
The .NET CLR one is almost 8 times faster(cpu time) than the T-SQL one. It's also
a whole lot easier to read, and can be used for all other RegEx's needed. You do however
need to get out of management studio to make it, and 1.5 seconds is for processing
almost 20000 email addresses still should be fast enough for most uses.
</p><p style="margin: 0in; font-family: Calibri; font-size: 11pt;" lang="en-US"></p><pre><span style="color: Black; background-color: transparent; font-family: Courier New; font-size: 11px;"><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">SET</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">STATISTICS</span> TIME <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">ON</span>     <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">select</span> *
    <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">from</span> [AW].[person].emailaddress <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">as</span> p
    <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">where</span> dbo.VALIDEMAIL(P.emailaddress)=1
    <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">select</span> *
    <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">from</span> [AW].[person].emailaddress <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">as</span> p
    <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">where</span> dbo.fn_RegexIsMatch(<span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;">RTRIM</span>(<span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;">LTRIM</span>(<span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;">lower</span>(P.emailaddress))),<br /><span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">'^[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$'</span>)=1
(19929 row(s) affected) SQL Server Execution Times: CPU time = 1466 ms, elapsed time
= 1911 ms. (19972 row(s) affected) SQL Server Execution Times: CPU time = 203 ms,
elapsed time = 380 ms. </span></pre>It's pretty cool to see that .NET performs good
within SQL as well. I am primarily a .NET developer but do have to use SQL quite a
bit as well, but the fact that .NET outperforms SQL both in readability and speed
inside SQL on some actions make my job a lot easier.<br /><p></p><br /><p></p><p></p><p></p><img width="0" height="0" src="http://gaute.amende.no/aggbug.ashx?id=930e8dc9-8c4f-471e-b272-98a26ed5c640" /></body>
      <title>Check valid emails in SQL. .NET CLR vs SQL approach </title>
      <guid isPermaLink="false">http://gaute.amende.no/PermaLink,guid,930e8dc9-8c4f-471e-b272-98a26ed5c640.aspx</guid>
      <link>http://gaute.amende.no/CheckValidEmailsInSQLNETCLRVsSQLApproach.aspx</link>
      <pubDate>Thu, 23 Oct 2008 08:48:20 GMT</pubDate>
      <description>

&lt;p style="margin: 0in; font-family: arial; font-size: 10pt; color: black;"&gt;
Checking if a email addresses is valid in SQL can be very convinient from time to
time. Here are two ways to do it in SQL, and a bit about them.
&lt;/p&gt;
&lt;p style="margin: 0in; font-family: arial; font-size: 10pt; color: black;"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0in; font-family: arial; font-size: 10pt; color: black;"&gt;
Here is a full SQL way to do this:
&lt;/p&gt;
&lt;p style="margin: 0in; font-family: arial; font-size: 10pt; color: black;"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;pre&gt;&lt;span style="color: Black; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;Create&lt;/span&gt; &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;function&lt;/span&gt; VALIDEMAIL(@s &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;varchar&lt;/span&gt;(255)) 
&lt;br&gt;
&lt;span style="color: Teal; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;--Returns
true if the string is a valid email address.&lt;/span&gt;
&lt;br&gt;
returns &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;bit&lt;/span&gt;
&lt;br&gt;
&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;as&lt;/span&gt;
&lt;br&gt;
&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;BEGIN&lt;/span&gt;
&lt;br&gt;
&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;DECLARE&lt;/span&gt; @u &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;VARCHAR&lt;/span&gt;(60),
@v &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;VARCHAR&lt;/span&gt;(60),
@x &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;VARCHAR&lt;/span&gt;(60),
@i &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;int&lt;/span&gt;,
@j &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;int&lt;/span&gt;,
@result &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;bit&lt;/span&gt;
&lt;br&gt;
&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;SET&lt;/span&gt; @result=1&lt;br&gt;
&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;set&lt;/span&gt; @s
= &lt;span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;rtrim&lt;/span&gt;(&lt;span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;ltrim&lt;/span&gt;(@s))&lt;br&gt;
&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;SET&lt;/span&gt; @i=&lt;span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;len&lt;/span&gt;(@s)-&lt;span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;CHARINDEX&lt;/span&gt;(&lt;span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;'@'&lt;/span&gt;,&lt;span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;reverse&lt;/span&gt;(@s))+1&lt;br&gt;
&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;if&lt;/span&gt; @i
&amp;lt;= 1 &lt;span style="color: Silver; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;or&lt;/span&gt; &lt;span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;len&lt;/span&gt;(@s)
&amp;lt; 5&lt;br&gt;
&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;begin&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;set&lt;/span&gt; @result
= 0&lt;br&gt;
&amp;nbsp; &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;goto&lt;/span&gt; done&lt;br&gt;
&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;end&lt;/span&gt;
&lt;br&gt;
&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;SET&lt;/span&gt; @u=&lt;span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;LEFT&lt;/span&gt;(@s,@i-1)&lt;br&gt;
&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;SET&lt;/span&gt; @j=&lt;span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;len&lt;/span&gt;(@s)-&lt;span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;CHARINDEX&lt;/span&gt;(&lt;span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;'.'&lt;/span&gt;,&lt;span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;reverse&lt;/span&gt;(@s))+1&lt;br&gt;
&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;SET&lt;/span&gt; @v=&lt;span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;RIGHT&lt;/span&gt;(@s,&lt;span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;LEN&lt;/span&gt;(@s)-@j)&lt;br&gt;
&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;if&lt;/span&gt; @j
&amp;lt; 3 &lt;span style="color: Silver; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;or&lt;/span&gt; @j
&amp;lt; @i&lt;br&gt;
&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;begin&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;set&lt;/span&gt; @result
= 0&lt;br&gt;
&amp;nbsp; &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;goto&lt;/span&gt; done&lt;br&gt;
&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;end&lt;/span&gt;
&lt;br&gt;
&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;SET&lt;/span&gt; @x=&lt;span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;substring&lt;/span&gt;(@s,@i+1,@j-@i-1)&lt;br&gt;
&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;IF&lt;/span&gt; &lt;span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;LEN&lt;/span&gt;(@x)&amp;lt;2&lt;br&gt;
&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;BEGIN&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;SET&lt;/span&gt; @result=0&lt;br&gt;
&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;GOTo&lt;/span&gt; done&lt;br&gt;
&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;END&lt;/span&gt;
&lt;br&gt;
&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;IF&lt;/span&gt; (&lt;span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;LEN&lt;/span&gt;(@x)=3) &lt;span style="color: Silver; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;AND&lt;/span&gt; (@x &lt;span style="color: Silver; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;NOT&lt;/span&gt; &lt;span style="color: Silver; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;LIKE&lt;/span&gt; &lt;span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;'[a-zA-Z][a-zA-Z][a-zA-Z]'&lt;/span&gt;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;Collate&lt;/span&gt;&amp;nbsp;
Latin1_General_BIN)&lt;br&gt;
&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;BEGIN&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;SET&lt;/span&gt; @result=0&lt;br&gt;
&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;GOTo&lt;/span&gt; done&lt;br&gt;
&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;END&lt;/span&gt;
&lt;br&gt;
&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;IF&lt;/span&gt; (&lt;span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;LEN&lt;/span&gt;(@x)=2) &lt;span style="color: Silver; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;AND&lt;/span&gt; (@x &lt;span style="color: Silver; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;NOT&lt;/span&gt; &lt;span style="color: Silver; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;LIKE&lt;/span&gt; &lt;span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;'[a-zA-Z][a-zA-Z]'&lt;/span&gt; &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;Collate&lt;/span&gt;&amp;nbsp;
Latin1_General_BIN)&lt;br&gt;
&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;BEGIN&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;SET&lt;/span&gt; @result=0&lt;br&gt;
&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;GOTo&lt;/span&gt; done&lt;br&gt;
&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;END&lt;/span&gt;
&lt;br&gt;
&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;SET&lt;/span&gt; @i=1&lt;br&gt;
&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;WHILE&lt;/span&gt; (@i&amp;lt;&lt;span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;LEN&lt;/span&gt;(@u))&lt;br&gt;
&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;BEGIN&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;IF&lt;/span&gt; &lt;span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;SUBSTRING&lt;/span&gt;(@u,@i,1) &lt;span style="color: Silver; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;NOT&lt;/span&gt; &lt;span style="color: Silver; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;LIKE&lt;/span&gt; &lt;span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;'[a-zA-Z0-9_\-.+=/!#$&amp;amp;''*%?^`{|}"@\\
]'&lt;/span&gt; &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;escape&lt;/span&gt; &lt;span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;'\'&lt;/span&gt; &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;Collate&lt;/span&gt;&amp;nbsp;
Latin1_General_BIN&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;BEGIN&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;SET&lt;/span&gt; @result=0&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;GOTo&lt;/span&gt; done&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;END&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;SET&lt;/span&gt; @i=@i+1&lt;br&gt;
&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;END&lt;/span&gt;
&lt;br&gt;
&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;SET&lt;/span&gt; @i=1&lt;br&gt;
&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;WHILE&lt;/span&gt; (@i&amp;lt;&lt;span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;LEN&lt;/span&gt;(@v))&lt;br&gt;
&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;BEGIN&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;IF&lt;/span&gt; &lt;span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;SUBSTRING&lt;/span&gt;(@v,@i,1) &lt;span style="color: Silver; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;NOT&lt;/span&gt; &lt;span style="color: Silver; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;LIKE&lt;/span&gt; &lt;span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;'[a-zA-Z]'&lt;/span&gt; &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;Collate&lt;/span&gt; Latin1_General_BIN&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;BEGIN&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;SET&lt;/span&gt; @result=0&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;GOTo&lt;/span&gt; done&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;END&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;SET&lt;/span&gt; @i=@i+1&lt;br&gt;
&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;END&lt;/span&gt;
&lt;br&gt;
&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;SET&lt;/span&gt; @i=1&lt;br&gt;
&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;WHILE&lt;/span&gt; (@i&amp;lt;&lt;span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;LEN&lt;/span&gt;(@x))&lt;br&gt;
&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;BEGIN&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;IF&lt;/span&gt; &lt;span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;SUBSTRING&lt;/span&gt;(@x,@i,1) &lt;span style="color: Silver; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;NOT&lt;/span&gt; &lt;span style="color: Silver; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;LIKE&lt;/span&gt; N&lt;span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;'[a-zA-Z\-.0-9]'&lt;/span&gt; &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;escape&lt;/span&gt; &lt;span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;'\'&lt;/span&gt; &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;Collate&lt;/span&gt;&amp;nbsp;
Latin1_General_BIN&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;BEGIN&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;SET&lt;/span&gt; @result=0&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;goto&lt;/span&gt; done&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;END&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;SET&lt;/span&gt; @i=@i+1&lt;br&gt;
&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;END&lt;/span&gt;
&lt;br&gt;
done:&lt;br&gt;
&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;return&lt;/span&gt; @result&lt;br&gt;
&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;END&lt;/span&gt;
&lt;br&gt;
GO&lt;br&gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;p style="margin: 0in; font-family: arial; font-size: 10pt; color: black;"&gt;
&lt;/p&gt;
&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;" lang="en-US"&gt;
Here is another way, where you insert .NET CLR code in the database. Here I use the
.NET RegEx.Ismatch, so I can use it for tons of other stuff as well with the right
input.&lt;br&gt;
&lt;/p&gt;
&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;" lang="en-US"&gt;
&lt;/p&gt;
&lt;pre&gt;&lt;span style="color: Black; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt; &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;using&lt;/span&gt; System; &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;using&lt;/span&gt; System.Collections.Generic; &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;using&lt;/span&gt; System.Text; &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;using&lt;/span&gt; Microsoft.SqlServer.Server; &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;using&lt;/span&gt; System.Data.SqlTypes; &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;using&lt;/span&gt; System.Text.RegularExpressions; &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;namespace&lt;/span&gt; SQLSignature
{ &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;public&lt;/span&gt; &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;class&lt;/span&gt; SqlFunctions
{ [SqlFunction(IsDeterministic &lt;span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;=&lt;/span&gt; &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;true&lt;/span&gt;,
DataAccess &lt;span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;=&lt;/span&gt; DataAccessKind.None)] &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;public&lt;/span&gt; &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;static&lt;/span&gt; SqlBoolean
fn_RegexIsMatch(SqlString input, SqlString pattern) { &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;return&lt;/span&gt; (SqlBoolean)Regex.IsMatch(input.Value,
pattern.Value); } } } &lt;/span&gt;&lt;/pre&gt;In SQL: 
&lt;br&gt;
&lt;pre&gt;&lt;span style="color: Black; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;CREATE&lt;/span&gt; ASSEMBLY
SQLSignature &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;FROM&lt;/span&gt; &lt;span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;'C:\CLR
Assemblies\Performance\SQLFunctions\bin\SQLFunctions.dll'&lt;/span&gt;; GO &lt;span style="color: Teal; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;--
Create fn_SQLSigCLR and fn_RegexReplace functions&lt;/span&gt; &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;CREATE&lt;/span&gt; &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;FUNCTION&lt;/span&gt; dbo.fn_RegexIsMatch(@input &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;AS&lt;/span&gt; &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;NVARCHAR&lt;/span&gt;(&lt;span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;MAX&lt;/span&gt;),@pattern &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;AS&lt;/span&gt; &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;NVARCHAR&lt;/span&gt;(&lt;span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;MAX&lt;/span&gt;))RETURNS &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;BIT&lt;/span&gt; &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;WITH&lt;/span&gt; RETURNS &lt;span style="color: Silver; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;NULL&lt;/span&gt; &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;ON&lt;/span&gt; &lt;span style="color: Silver; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;NULL&lt;/span&gt; INPUT
EXTERNAL NAME SQLSignature.SQLFunctions.fn_RegexIsMatch; GO &lt;/span&gt;&lt;/pre&gt;This can
be run with a command like:&lt;br&gt;
&lt;br&gt;
&lt;pre&gt;&lt;span style="color: Black; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;select&lt;/span&gt; *
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;from&lt;/span&gt; [AW].[person].emailaddress &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;as&lt;/span&gt; p
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;where&lt;/span&gt; dbo.fn_RegexIsMatch(&lt;span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;RTRIM&lt;/span&gt;(&lt;span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;LTRIM&lt;/span&gt;(&lt;span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;lower&lt;/span&gt;(P.emailaddress))),&lt;br&gt;
&lt;span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt; '^[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$'&lt;/span&gt;)=1 &lt;/span&gt;&lt;/pre&gt;
&lt;br&gt;
&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;" lang="en-US"&gt;
I did some timings on the two functions and as you can see below there are big differences.
The .NET CLR one is almost 8 times faster(cpu time) than the T-SQL one. It's also
a whole lot easier to read, and can be used for all other RegEx's needed. You do however
need to get out of management studio to make it, and 1.5 seconds is for processing
almost 20000 email addresses still should be fast enough for most uses.
&lt;/p&gt;
&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;" lang="en-US"&gt;
&lt;/p&gt;
&lt;pre&gt;&lt;span style="color: Black; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;SET&lt;/span&gt; &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;STATISTICS&lt;/span&gt; TIME &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;ON&lt;/span&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;select&lt;/span&gt; *
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;from&lt;/span&gt; [AW].[person].emailaddress &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;as&lt;/span&gt; p
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;where&lt;/span&gt; dbo.VALIDEMAIL(P.emailaddress)=1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;select&lt;/span&gt; *
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;from&lt;/span&gt; [AW].[person].emailaddress &lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;as&lt;/span&gt; p
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;where&lt;/span&gt; dbo.fn_RegexIsMatch(&lt;span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;RTRIM&lt;/span&gt;(&lt;span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;LTRIM&lt;/span&gt;(&lt;span style="color: Fuchsia; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;lower&lt;/span&gt;(P.emailaddress))),&lt;br&gt;
&lt;span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;'^[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$'&lt;/span&gt;)=1
(19929 row(s) affected) SQL Server Execution Times: CPU time = 1466 ms, elapsed time
= 1911 ms. (19972 row(s) affected) SQL Server Execution Times: CPU time = 203 ms,
elapsed time = 380 ms. &lt;/span&gt;&lt;/pre&gt;It's pretty cool to see that .NET performs good
within SQL as well. I am primarily a .NET developer but do have to use SQL quite a
bit as well, but the fact that .NET outperforms SQL both in readability and speed
inside SQL on some actions make my job a lot easier.&lt;br&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;br&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://gaute.amende.no/aggbug.ashx?id=930e8dc9-8c4f-471e-b272-98a26ed5c640" /&gt;</description>
      <comments>http://gaute.amende.no/CommentView,guid,930e8dc9-8c4f-471e-b272-98a26ed5c640.aspx</comments>
      <category>.NET</category>
      <category>T-SQL</category>
    </item>
    <item>
      <trackback:ping>http://gaute.amende.no/Trackback.aspx?guid=b81cf1b6-4dc4-44d6-90e1-46a9b9bcfcdc</trackback:ping>
      <pingback:server>http://gaute.amende.no/pingback.aspx</pingback:server>
      <pingback:target>http://gaute.amende.no/PermaLink,guid,b81cf1b6-4dc4-44d6-90e1-46a9b9bcfcdc.aspx</pingback:target>
      <dc:creator>Gaute Magnussen</dc:creator>
      <wfw:comment>http://gaute.amende.no/CommentView,guid,b81cf1b6-4dc4-44d6-90e1-46a9b9bcfcdc.aspx</wfw:comment>
      <wfw:commentRss>http://gaute.amende.no/SyndicationService.asmx/GetEntryCommentsRss?guid=b81cf1b6-4dc4-44d6-90e1-46a9b9bcfcdc</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Last week I had a problem where I needed a hierarchical chain of results. I had to
get results of all organisations above my organsiation in a hierarcy. I knew how I
would do this by recursion in C#, but had no idea how to get it done in SQL. But asking
a bit around, and searching the web I got a really nice solution using the to me new
WITH-command. And it seems quite fast aswell. Here is a SQL script with some testdata:
</p>
        <pre>
          <span style="font-size: 11px; color: black; font-family: Courier New; background-color: transparent;">
            <span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">Create</span>
            <span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">table</span> #Relations
( ID <span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">int</span><span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">PRIMARY</span><span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">KEY</span>,
ChildId <span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">int</span>,
name <span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">varchar</span>(50)
) <span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">insert</span><span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">into</span> #Relations <span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">values</span> (5,
4, <span style="font-size: 11px; color: red; font-family: Courier New; background-color: transparent;">'Me'</span>) <span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">insert</span><span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">into</span> #Relations <span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">values</span> (4,
3, <span style="font-size: 11px; color: red; font-family: Courier New; background-color: transparent;">'Father'</span>) <span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">insert</span><span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">into</span> #Relations <span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">values</span> (3,
2, <span style="font-size: 11px; color: red; font-family: Courier New; background-color: transparent;">'Grandpa'</span>) <span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">insert</span><span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">into</span> #Relations <span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">values</span> (2,
1, <span style="font-size: 11px; color: red; font-family: Courier New; background-color: transparent;">'Great
Grandpa'</span>) <span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">insert</span><span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">Into</span> #Relations <span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">values</span> (1, <span style="font-size: 11px; color: silver; font-family: Courier New; background-color: transparent;">null</span>, <span style="font-size: 11px; color: red; font-family: Courier New; background-color: transparent;">'Great
Old Grandpa'</span>) <span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">declare</span> @startid <span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">int</span><span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">set</span> @startid
= 5 ;<span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">WITH</span> Names <span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">AS</span> ( <span style="font-size: 11px; color: teal; font-family: Courier New; background-color: transparent;">--Gets
the starting line</span><span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">SELECT</span> * <span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">FROM</span> #Relations <span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">where</span> id
= @startid <span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">UNION</span><span style="font-size: 11px; color: silver; font-family: Courier New; background-color: transparent;">ALL</span><span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">SELECT</span> r.* <span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">FROM</span> #Relations
r <span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">INNER</span><span style="font-size: 11px; color: silver; font-family: Courier New; background-color: transparent;">JOIN</span> names
n <span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">ON</span> n.ChildId=r.id
) <span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">select</span> * <span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;">from</span> names</span>
        </pre>
        <p>
Here are the results. As you can see, it works;)
</p>
        <p>
          <font size="1">ID ChildId name<br /></font>
          <font size="1">---------- ----------- --------------------------------------------------<br />
5 4 Me<br />
4 3 Father<br />
3 2 Grandpa<br />
2 1 Great Grandpa<br />
1 NULL Great Old Grandpa<br />
(5 row(s) affected)</font>
        </p>
        <font size="1">
        </font>
        <img width="0" height="0" src="http://gaute.amende.no/aggbug.ashx?id=b81cf1b6-4dc4-44d6-90e1-46a9b9bcfcdc" />
      </body>
      <title>Get a hierarchical chain of results in SQL</title>
      <guid isPermaLink="false">http://gaute.amende.no/PermaLink,guid,b81cf1b6-4dc4-44d6-90e1-46a9b9bcfcdc.aspx</guid>
      <link>http://gaute.amende.no/GetAHierarchicalChainOfResultsInSQL.aspx</link>
      <pubDate>Fri, 22 Aug 2008 11:38:13 GMT</pubDate>
      <description>&lt;p&gt;
Last week I had a problem where I needed a hierarchical chain of results. I had to
get results of all organisations above my organsiation in a hierarcy. I knew how I
would do this by recursion in C#, but had no idea how to get it done in SQL. But asking
a bit around, and searching the web I got a really nice solution using the to me new
WITH-command. And it seems quite fast aswell. Here is a SQL script with some testdata:
&lt;/p&gt;
&lt;pre&gt;&lt;span style="font-size: 11px; color: black; font-family: Courier New; background-color: transparent;"&gt;&lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;Create&lt;/span&gt; &lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;table&lt;/span&gt; #Relations
( ID &lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;int&lt;/span&gt; &lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;PRIMARY&lt;/span&gt; &lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;KEY&lt;/span&gt;,
ChildId &lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;int&lt;/span&gt;,
name &lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;varchar&lt;/span&gt;(50)
) &lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;insert&lt;/span&gt; &lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;into&lt;/span&gt; #Relations &lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;values&lt;/span&gt; (5,
4, &lt;span style="font-size: 11px; color: red; font-family: Courier New; background-color: transparent;"&gt;'Me'&lt;/span&gt;) &lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;insert&lt;/span&gt; &lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;into&lt;/span&gt; #Relations &lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;values&lt;/span&gt; (4,
3, &lt;span style="font-size: 11px; color: red; font-family: Courier New; background-color: transparent;"&gt;'Father'&lt;/span&gt;) &lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;insert&lt;/span&gt; &lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;into&lt;/span&gt; #Relations &lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;values&lt;/span&gt; (3,
2, &lt;span style="font-size: 11px; color: red; font-family: Courier New; background-color: transparent;"&gt;'Grandpa'&lt;/span&gt;) &lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;insert&lt;/span&gt; &lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;into&lt;/span&gt; #Relations &lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;values&lt;/span&gt; (2,
1, &lt;span style="font-size: 11px; color: red; font-family: Courier New; background-color: transparent;"&gt;'Great
Grandpa'&lt;/span&gt;) &lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;insert&lt;/span&gt; &lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;Into&lt;/span&gt; #Relations &lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;values&lt;/span&gt; (1, &lt;span style="font-size: 11px; color: silver; font-family: Courier New; background-color: transparent;"&gt;null&lt;/span&gt;, &lt;span style="font-size: 11px; color: red; font-family: Courier New; background-color: transparent;"&gt;'Great
Old Grandpa'&lt;/span&gt;) &lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;declare&lt;/span&gt; @startid &lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;int&lt;/span&gt; &lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;set&lt;/span&gt; @startid
= 5 ;&lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;WITH&lt;/span&gt; Names &lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;AS&lt;/span&gt; ( &lt;span style="font-size: 11px; color: teal; font-family: Courier New; background-color: transparent;"&gt;--Gets
the starting line&lt;/span&gt; &lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;SELECT&lt;/span&gt; * &lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;FROM&lt;/span&gt; #Relations &lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;where&lt;/span&gt; id
= @startid &lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;UNION&lt;/span&gt; &lt;span style="font-size: 11px; color: silver; font-family: Courier New; background-color: transparent;"&gt;ALL&lt;/span&gt; &lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;SELECT&lt;/span&gt; r.* &lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;FROM&lt;/span&gt; #Relations
r &lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;INNER&lt;/span&gt; &lt;span style="font-size: 11px; color: silver; font-family: Courier New; background-color: transparent;"&gt;JOIN&lt;/span&gt; names
n &lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;ON&lt;/span&gt; n.ChildId=r.id
) &lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;select&lt;/span&gt; * &lt;span style="font-size: 11px; color: blue; font-family: Courier New; background-color: transparent;"&gt;from&lt;/span&gt; names&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
Here are the results. As you can see, it works;)
&lt;/p&gt;
&lt;p&gt;
&lt;font size="1"&gt;ID ChildId name&lt;br&gt;
&lt;/font&gt;&lt;font size="1"&gt;---------- ----------- --------------------------------------------------&lt;br&gt;
5 4 Me&lt;br&gt;
4 3 Father&lt;br&gt;
3 2 Grandpa&lt;br&gt;
2 1 Great Grandpa&lt;br&gt;
1 NULL Great Old Grandpa&lt;br&gt;
(5 row(s) affected)&lt;/font&gt;
&lt;/p&gt;
&lt;font size="1"&gt;&lt;/font&gt;&lt;img width="0" height="0" src="http://gaute.amende.no/aggbug.ashx?id=b81cf1b6-4dc4-44d6-90e1-46a9b9bcfcdc" /&gt;</description>
      <comments>http://gaute.amende.no/CommentView,guid,b81cf1b6-4dc4-44d6-90e1-46a9b9bcfcdc.aspx</comments>
      <category>T-SQL</category>
    </item>
  </channel>
</rss>