<?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>Shimon Krokhmal's blog - database</title>
    <link>http://www.krokhmal.com/</link>
    <description>medium : .NET | JavaScript | Secure coding | Databases | Sql Server | Oracle | CodeSmith | SPS | Life</description>
    <language>en-us</language>
    <copyright>Shimon Krokhmal</copyright>
    <lastBuildDate>Fri, 26 Jan 2007 08:21:34 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.0.7226.0</generator>
    <managingEditor>Shimonkr@gmail.com</managingEditor>
    <webMaster>Shimonkr@gmail.com</webMaster>
    <item>
      <trackback:ping>http://www.krokhmal.com/Trackback.aspx?guid=a9a74314-b878-4122-b2d8-e2ec21e0f1ee</trackback:ping>
      <pingback:server>http://www.krokhmal.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.krokhmal.com/PermaLink,guid,a9a74314-b878-4122-b2d8-e2ec21e0f1ee.aspx</pingback:target>
      <dc:creator>Shimon krokhmal</dc:creator>
      <wfw:comment>http://www.krokhmal.com/CommentView,guid,a9a74314-b878-4122-b2d8-e2ec21e0f1ee.aspx</wfw:comment>
      <wfw:commentRss>http://www.krokhmal.com/SyndicationService.asmx/GetEntryCommentsRss?guid=a9a74314-b878-4122-b2d8-e2ec21e0f1ee</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
A friend calls me earlier today(and wakes me up), with a problem on a system that
he is maintaining.<br />
since the customer needed the system ASAP, he asked me to deal with it .
</p>
        <p>
So, what is the problem ?<br /><br />
getting in to the system, wins the happy user with this error message :
</p>
        <p>
          <strong>8007000e System resource exceeded<br />
Microsoft OLE DB Provider for ODBC Drivers error '8007000e' 
<br />
[Microsoft][ODBC Microsoft Access Driver] System resource exceeded.</strong>
        </p>
        <p>
needless to say that is an "ASP-Access" system.
</p>
        <p>
lets review all our facts :
</p>
        <ul>
          <li>
The system written in ASP 
</li>
          <li>
The system's database is Access 
</li>
          <li>
It deployed on a shared hosting server 
</li>
          <li>
the system sends some error message - probably DB related</li>
        </ul>
        <p>
after googling a while, got the answer that the problem is connection pooling related.<br />
this could mean one of two things :
</p>
        <ol>
          <li>
There are places in the system which the connection not closed properly, which overloads
the connection pool. 
</li>
          <li>
There are too many simultaneous users, which cousing too many connections at the same
time.</li>
        </ol>
        <p>
Since there is only one user on the system, the second option is probably not the
answer.
</p>
        <p>
so, how do we clear the connection pool on a shared hosting server ???
</p>
        <p>
lets see what are the options (or to be exact : what are our limits on shared
hosting on that issue ?)
</p>
        <ul>
          <li>
We can't access the IIS configurations. 
</li>
          <li>
We can't get a remote desktop connection (is it too much to ask ?) 
</li>
          <li>
We don't have an access to the connection pool configurations 
</li>
          <li>
We cant restart the server.</li>
        </ul>
        <p>
Here is the solution :
</p>
        <ol>
          <li>
Access to the system to get the error. 
</li>
          <li>
rename the DB from db.mdb to db1.mdb 
</li>
          <li>
run the system again (this is an important step), 
<br />
the system will think that it's missing it's database and recycle the connection pool(mission
accomplished) 
</li>
          <li>
rename the database file to the original name (db.mdb) 
</li>
          <li>
run the system again.</li>
        </ol>
        <p>
now, i have to say , that this is a problem solver for the short run,<br />
whatever caused the problem will probably cause it again at some point.<br />
so, the best solution , is to do some harsh code review and find the problem (where
the connection is opened but not closed...)
</p>
        <p>
take care.
</p>
        <img width="0" height="0" src="http://www.krokhmal.com/aggbug.ashx?id=a9a74314-b878-4122-b2d8-e2ec21e0f1ee" />
        <br />
        <hr />
Shimon krokhmal, a part of the Krokhmal family</body>
      <title>Solving the 8007000e System resource exceeded error</title>
      <guid isPermaLink="false">http://www.krokhmal.com/PermaLink,guid,a9a74314-b878-4122-b2d8-e2ec21e0f1ee.aspx</guid>
      <link>http://www.krokhmal.com/2007/01/26/SolvingThe8007000eSystemResourceExceededError.aspx</link>
      <pubDate>Fri, 26 Jan 2007 08:21:34 GMT</pubDate>
      <description>&lt;p&gt;
A friend calls me earlier today(and wakes me up), with a problem on a system that
he is maintaining.&lt;br&gt;
since the customer needed the system ASAP, he asked me to deal with it .
&lt;/p&gt;
&lt;p&gt;
So, what is the problem ?&lt;br&gt;
&lt;br&gt;
getting in to the system, wins the happy user with this error message :
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;8007000e System resource exceeded&lt;br&gt;
Microsoft OLE DB Provider for ODBC Drivers error '8007000e' 
&lt;br&gt;
[Microsoft][ODBC Microsoft Access Driver] System resource exceeded.&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
needless to say that is an "ASP-Access" system.
&lt;/p&gt;
&lt;p&gt;
lets review all our facts :
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
The system written in ASP 
&lt;li&gt;
The system's database is Access 
&lt;li&gt;
It deployed on a shared hosting server 
&lt;li&gt;
the system sends some error message - probably DB related&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
after googling a while, got the answer that the problem is connection pooling related.&lt;br&gt;
this could mean one of two things :
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
There are places in the system which the connection not closed properly, which overloads
the connection pool. 
&lt;li&gt;
There are too many simultaneous users, which cousing too many connections at the same
time.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Since there is only one user on the system, the second option is probably not the
answer.
&lt;/p&gt;
&lt;p&gt;
so, how do we clear the connection pool on a shared hosting server ???
&lt;/p&gt;
&lt;p&gt;
lets see what are the options (or to be exact&amp;nbsp;: what are our limits on shared
hosting on that issue ?)
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
We can't access the IIS configurations. 
&lt;li&gt;
We can't get a remote desktop connection (is it too much to ask ?) 
&lt;li&gt;
We don't have an access to the connection pool configurations 
&lt;li&gt;
We cant restart the server.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Here is the solution :
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Access to the system to get the error. 
&lt;li&gt;
rename the DB from db.mdb to db1.mdb 
&lt;li&gt;
run the system again (this is an important step), 
&lt;br&gt;
the system will think that it's missing it's database and recycle the connection pool(mission
accomplished) 
&lt;li&gt;
rename the database file to the original name (db.mdb) 
&lt;li&gt;
run the system again.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
now, i have to say , that this is a problem solver for the short run,&lt;br&gt;
whatever caused the problem will probably cause it again at some point.&lt;br&gt;
so, the best solution , is to do some harsh code review and find the problem (where
the connection is opened but not closed...)
&lt;/p&gt;
&lt;p&gt;
take care.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.krokhmal.com/aggbug.ashx?id=a9a74314-b878-4122-b2d8-e2ec21e0f1ee" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Shimon krokhmal, a part of the Krokhmal family</description>
      <comments>http://www.krokhmal.com/CommentView,guid,a9a74314-b878-4122-b2d8-e2ec21e0f1ee.aspx</comments>
      <category>ASP</category>
      <category>database</category>
    </item>
    <item>
      <trackback:ping>http://www.krokhmal.com/Trackback.aspx?guid=8d51eb7c-3975-4fcf-a2e8-75c8b1443661</trackback:ping>
      <pingback:server>http://www.krokhmal.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.krokhmal.com/PermaLink,guid,8d51eb7c-3975-4fcf-a2e8-75c8b1443661.aspx</pingback:target>
      <dc:creator>Shimon krokhmal</dc:creator>
      <wfw:comment>http://www.krokhmal.com/CommentView,guid,8d51eb7c-3975-4fcf-a2e8-75c8b1443661.aspx</wfw:comment>
      <wfw:commentRss>http://www.krokhmal.com/SyndicationService.asmx/GetEntryCommentsRss?guid=8d51eb7c-3975-4fcf-a2e8-75c8b1443661</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
remember this neat syntax that exists in oracle database for hierarchy selects ?<br />
actually , its pretty simple :<br /><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">SELECT</span> last_name,
employee_id, manager_id, LEVEL<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">FROM</span> employees<br /><font color="#0000ff">START</font><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">WITH</span> employee_id
= 100<br /><font color="#0000ff">CONNECT <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">BY</span> PRIOR</font> employee_id
= manager_id;</span><br /><br />
ever tried to do the same in sql server ?<br />
well, these kind of syntax just does not exist,<br />
we need to work very hard to create such a feature in our database.<br /></p>
        <p>
so, what do we have:
</p>
        <ul>
          <li>
a table that contains entities 
</li>
          <li>
each entity connected to some father entity 
</li>
          <li>
each connection describes a "father - son" relation between the two entities</li>
        </ul>
        <p>
lets not forget the things we need to relay on , when implementing :
</p>
        <ul>
          <li>
what will happen when we will delete the father of some sub tree ? 
</li>
          <li>
what should we do when we update/add a record ? 
</li>
          <li>
how will we select the data ? 
</li>
          <li>
algorithm efficiency is crucial, if we will need to wait 5 minutes for the data, it's
not worth it</li>
        </ul>
        <p>
the first (but apparently the worst) idea that came to my mind is recursion<br />
lets look at this table :
</p>
        <p>
 
</p>
        <table border="1">
          <tbody>
            <tr>
              <td>
                <strong>EmployeeID</strong>
              </td>
              <td>
                <strong>Name</strong>
              </td>
              <td>
                <strong>BossID</strong>
              </td>
            </tr>
            <tr>
              <td>
                <p align="center">
1
</p>
              </td>
              <td>
                <p align="center">
shimon
</p>
              </td>
              <td>
                <p align="center">
NULL
</p>
              </td>
            </tr>
            <tr>
              <td>
                <p align="center">
2
</p>
              </td>
              <td>
                <p align="center">
yossi
</p>
              </td>
              <td>
                <p align="center">
1
</p>
              </td>
            </tr>
            <tr>
              <td>
                <p align="center">
3
</p>
              </td>
              <td>
                <p align="center">
Gaby
</p>
              </td>
              <td>
                <p align="center">
1
</p>
              </td>
            </tr>
            <tr>
              <td>
                <p align="center">
4
</p>
              </td>
              <td>
                <p align="center">
koby
</p>
              </td>
              <td>
                <p align="center">
3
</p>
              </td>
            </tr>
            <tr>
              <td>
                <p align="center">
5
</p>
              </td>
              <td>
                <p align="center">
jack
</p>
              </td>
              <td>
                <p align="center">
3
</p>
              </td>
            </tr>
          </tbody>
        </table>
        <p>
 
</p>
        <p>
we have we that the employee shimon is the "big boss" (because there is no other boss
above him),<br />
under shimon we have the employees Gaby and yossi,<br />
and under Gaby, we have another 2 employees : Koby and jack
</p>
        <p>
the recursive solution is to write some stored procedure that will receive the employeeID
and return as a data-Table the results<br />
i will not add the code for this solution and surely will not recommend it because
it was many problems :
</p>
        <ul>
          <li>
for each record we received as a descendant , 
<br />
we need to run with the function and get her descendants, 
<br />
and so on, until there are no descendants for the node 
</li>
          <li>
we are limited to 32 levels of hierarchy 
</li>
          <li>
the runtime will depend on the row count that is in the table (we will need to run
on each of the rows one at the time) 
</li>
          <li>
the run on the node will look like this :<br /><img height="200" alt="heirarchy.jpg" src="http://www.krokhmal.com/Blog/content/binary/heirarchy.jpg" width="300" border="0" /><br /><br /></li>
        </ul>
        <p>
by the way, the most common way that I've seen to select hierarchical structure,<br />
is simply by setting a join between the levels in the select query.<br />
for example :
</p>
        <p>
          <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">SELECT</span> TopBoss.Name
TopBoss, Boss.Name Boss, Employees.Name Employee<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">FROM</span> Employees 
<br /><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> Employees <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">AS</span> Boss <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">ON</span> Employees.BossID=Boss.EmployeeID<br /><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> Employees
TopBoss <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">ON</span> Boss.BossID=TopBoss.EmployeeID</span>
        </p>
        <p>
this apply to the selection of three levels
</p>
        <p>
For each level, you'd need to join the table to itself...not an attractive option
if you have 5 or more levels ,<br />
you don't know how many levels you will have to select, there is no way can control
it!<br />
It would be great if it could join itself as many times as needed. This is called
a recursive join, and though some database products support it (Oracle has the CONNECT
BY syntax) SQL Server is not one of them.
</p>
        <p>
the other way is based on a thread that i read <a href="http://www.sqlteam.com/Forums/topic.asp?TOPIC_ID=2828">here</a> about
hierarchies,<br /></p>
        <p>
lets create a table :<br /></p>
        <p>
          <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> Tree
(<br />
Node <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">int</span><span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">NOT</span><span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">NULL</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">IDENTITY</span>(100,
1),<br />
ParentNode <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">int</span>, 
<br />
EmployeeID <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">int</span><span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">NOT</span><span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">NULL</span>, 
<br />
Depth <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">tinyint</span>,<br />
Lineage <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">varchar</span>(255)
)</span>
        </p>
        <p>
the extra fields that has been added are the "<strong>lineage</strong>" and the "<strong>depth</strong>"
</p>
        <ul>
          <li>
Depth - for saving the current depth of the record in the hierarchy 
</li>
          <li>
Lineage - for saving all the ancestors of the record as a concatenated string</li>
        </ul>
        <p>
after filling the needed data for relations, the table looks like this :
</p>
        <p>
          <table cellspacing="0" cellpadding="2" border="1">
            <tbody>
              <tr>
                <td class="head">
Node</td>
                <td class="head">
ParentNode</td>
                <td class="head">
EmployeeID</td>
                <td class="head">
Depth</td>
                <td class="head">
Lineage</td>
              </tr>
              <tr>
                <td class="n">
100</td>
                <td class="n">
NULL</td>
                <td class="n">
1001</td>
                <td class="n">
NULL</td>
                <td class="n">
NULL</td>
              </tr>
              <tr>
                <td class="n">
101</td>
                <td class="n">
100</td>
                <td class="n">
1002</td>
                <td class="n">
NULL</td>
                <td class="n">
NULL</td>
              </tr>
              <tr>
                <td class="n">
102</td>
                <td class="n">
101</td>
                <td class="n">
1003</td>
                <td class="n">
NULL</td>
                <td class="n">
NULL</td>
              </tr>
              <tr>
                <td class="n">
103</td>
                <td class="n">
102</td>
                <td class="n">
1004</td>
                <td class="n">
NULL</td>
                <td class="n">
NULL</td>
              </tr>
              <tr>
                <td class="n">
104</td>
                <td class="n">
102</td>
                <td class="n">
1005</td>
                <td class="n">
NULL</td>
                <td class="n">
NULL</td>
              </tr>
              <tr>
                <td class="n">
105</td>
                <td class="n">
102</td>
                <td class="n">
1006</td>
                <td class="n">
NULL</td>
                <td class="n">
NULL</td>
              </tr>
            </tbody>
          </table>
        </p>
        <p>
The next part is to find the root node of the tree, also known as the top-level, etc. 
<br />
That's the node that has no parent (Null), so we will start there and set the Lineage
column as the root: 
</p>
        <p>
          <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">UPDATE</span> Tree <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">SET</span> Lineage=<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">'/'</span>,
Depth=0 <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">WHERE</span> ParentNode <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">Is</span><span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">Null</span></span>
        </p>
        <p>
Once we did that, 
<br />
we can then update the rows who are the descendant of the root node:
</p>
        <p>
          <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">WHILE</span>
            <span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">EXISTS</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> Tree <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">WHERE</span> Depth <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">Is</span><span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">Null</span>) <br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   UPDATE</span> T <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">SET</span> T.depth
= P.Depth + 1, <br />
   T.Lineage = P.Lineage + <span style="FONT-SIZE: 11px; COLOR: fuchsia; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">Ltrim</span>(<span style="FONT-SIZE: 11px; COLOR: fuchsia; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">Str</span>(T.ParentNode,6,0))
+ <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">'/'</span> <br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   FROM</span> Tree <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">AS</span> T <br /><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> Tree <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">AS</span> P <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">ON</span> (T.ParentNode=P.Node) <br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   WHERE</span> P.Depth&gt;=0 <br /><span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   AND</span> P.Lineage <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">Is</span><span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">Not</span><span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">Null</span> <br /><span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   AND</span> T.Depth <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">Is</span><span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">Null</span></span>
        </p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
              <font face="Verdana" color="#003300" size="2">
              </font>
            </span>
          </span> 
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
              <font face="Verdana" color="#003300" size="2">this
loop will run once for each level of the hierarchy (<strong>not for each node as the
recursion method</strong>.) 
<br />
so, with data representation of 10,000 records with 8 levels of hierarchy, 
<br />
this code will run only 8 times to populate the needed data of the "lineage" field
and the "depth" field, and this "heavy" procedure will happen only once at the setup.<br />
the table should look like this after the given operation : 
<br /><br /><br /></font>
            </span>
          </span>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
              <font face="Verdana" color="#003300" size="2">
                <br />
              </font>
            </span>
          </span>
        </p>
        <table cellspacing="0" cellpadding="2" border="1">
          <tbody>
            <tr>
              <td class="head">
Node</td>
              <td class="head">
ParentNode</td>
              <td class="head">
EmployeeID</td>
              <td class="head">
Depth</td>
              <td class="head">
Lineage</td>
            </tr>
            <tr>
              <td class="n">
100</td>
              <td class="n">
NULL</td>
              <td class="n">
1001</td>
              <td class="n">
0</td>
              <td class="n">
/</td>
            </tr>
            <tr>
              <td class="n">
101</td>
              <td class="n">
100</td>
              <td class="n">
1002</td>
              <td class="n">
1</td>
              <td class="n">
/100/</td>
            </tr>
            <tr>
              <td class="n">
102</td>
              <td class="n">
101</td>
              <td class="n">
1003</td>
              <td class="n">
2</td>
              <td class="n">
/100/101/</td>
            </tr>
            <tr>
              <td class="n">
103</td>
              <td class="n">
102</td>
              <td class="n">
1004</td>
              <td class="n">
3</td>
              <td class="n">
/100/101/102/</td>
            </tr>
            <tr>
              <td class="n">
104</td>
              <td class="n">
102</td>
              <td class="n">
1005</td>
              <td class="n">
3</td>
              <td class="n">
/100/101/102/</td>
            </tr>
            <tr>
              <td class="n">
105</td>
              <td class="n">
102</td>
              <td class="n">
1006</td>
              <td class="n">
3</td>
              <td class="n">
/100/101/102/</td>
            </tr>
          </tbody>
        </table>
        <p>
 
</p>
        <p>
You'll notice that for each node, the entire lineage back to the root is stored. This
means that finding someone's boss, or their boss' boss, doesn't require any self-joins
or recursion to create an indented list. In fact, it can be accomplished with a single
SELECT.
</p>
        <p>
          <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">SELECT</span>
            <span style="FONT-SIZE: 11px; COLOR: fuchsia; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">Space</span>(T.Depth*2)
+ E.Name <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">AS</span> Name<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">FROM</span> Employees
E 
<br /><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> Tree
T <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">ON</span> E.EmployeeID=T.EmployeeID<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">ORDER</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">BY</span> T.Lineage
+ <span style="FONT-SIZE: 11px; COLOR: fuchsia; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">Ltrim</span>(<span style="FONT-SIZE: 11px; COLOR: fuchsia; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">Str</span>(T.Node,6,0))</span>
        </p>
        <p>
 
</p>
        <p>
maintaining the table is really not a big deal if we will use triggers.<br />
think about the new inserted record as the row that has not been filled in the setup
process.<br />
so the insert trigger should be : 
<br /><br /></p>
        <p>
          <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">UPDATE</span> T <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">SET</span> T.depth
= P.Depth + 1, 
<br />
T.Lineage = P.Lineage + <span style="FONT-SIZE: 11px; COLOR: fuchsia; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">Ltrim</span>(<span style="FONT-SIZE: 11px; COLOR: fuchsia; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">Str</span>(T.ParentNode,6,0))
+ <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">'/'</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">FROM</span> Tree <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">AS</span> T 
<br /><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> Tree <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">AS</span> P <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">ON</span> (T.ParentNode=P.Node) 
<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">WHERE</span> P.Depth&gt;=0 
<br /><span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">AND</span> P.Lineage <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">Is</span><span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">Not</span><span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">Null</span><br /><span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">AND</span> T.Depth <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">Is</span><span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">Null</span><br /></span>
        </p>
        <p>
 
</p>
        <p>
the update trigger should do pretty much the same : building the 2 extra field all
over again.
</p>
        <p>
suggestions and request will be repplied :)
</p>
        <img width="0" height="0" src="http://www.krokhmal.com/aggbug.ashx?id=8d51eb7c-3975-4fcf-a2e8-75c8b1443661" />
        <br />
        <hr />
Shimon krokhmal, a part of the Krokhmal family</body>
      <title>hierarchy implementation in SQL server 2000</title>
      <guid isPermaLink="false">http://www.krokhmal.com/PermaLink,guid,8d51eb7c-3975-4fcf-a2e8-75c8b1443661.aspx</guid>
      <link>http://www.krokhmal.com/2006/08/16/hierarchyImplementationInSQLServer2000.aspx</link>
      <pubDate>Wed, 16 Aug 2006 22:47:18 GMT</pubDate>
      <description>&lt;p&gt;
remember this neat syntax that exists in oracle database for hierarchy selects ?&lt;br&gt;
actually , its pretty simple :&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;SELECT&lt;/span&gt; last_name,
employee_id, manager_id, LEVEL&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;FROM&lt;/span&gt; employees&lt;br&gt;
&lt;font color=#0000ff&gt;START&lt;/font&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;WITH&lt;/span&gt; employee_id
= 100&lt;br&gt;
&lt;font color=#0000ff&gt;CONNECT &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;BY&lt;/span&gt; PRIOR&lt;/font&gt; employee_id
= manager_id;&lt;/span&gt;
&lt;br&gt;
&lt;br&gt;
ever tried to do the same in sql server ?&lt;br&gt;
well, these kind of syntax just does not exist,&lt;br&gt;
we need to work very hard to create such a feature in our database.&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
so, what do we have:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
a table that contains entities 
&lt;li&gt;
each entity connected to some father entity 
&lt;li&gt;
each connection describes a "father - son" relation between the two entities&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
lets not forget the things we need to relay on , when implementing :
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
what will happen when we will delete the father of some sub tree ? 
&lt;li&gt;
what should we do when we update/add a record ? 
&lt;li&gt;
how will we select the data ? 
&lt;li&gt;
algorithm efficiency is crucial, if we will need to wait 5 minutes for the data, it's
not worth it&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
the first (but apparently the worst) idea that came to my mind is recursion&lt;br&gt;
lets look at this table :
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;table border=1&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;EmployeeID&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Name&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;BossID&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p align=center&gt;
1
&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p align=center&gt;
shimon
&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p align=center&gt;
NULL
&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p align=center&gt;
2
&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p align=center&gt;
yossi
&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p align=center&gt;
1
&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p align=center&gt;
3
&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p align=center&gt;
Gaby
&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p align=center&gt;
1
&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p align=center&gt;
4
&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p align=center&gt;
koby
&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p align=center&gt;
3
&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p align=center&gt;
5
&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p align=center&gt;
jack
&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p align=center&gt;
3
&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
we have we that the employee shimon is the "big boss" (because there is no other boss
above him),&lt;br&gt;
under shimon we have the employees Gaby and yossi,&lt;br&gt;
and under Gaby, we have another 2 employees : Koby and jack
&lt;/p&gt;
&lt;p&gt;
the recursive solution is to write some stored procedure that will receive the employeeID
and return as a data-Table the results&lt;br&gt;
i will not add the code for this solution and surely will not recommend it because
it was many problems :
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
for each record we received as a descendant , 
&lt;br&gt;
we need to run with the function and get her descendants, 
&lt;br&gt;
and so on, until there are no descendants for the node 
&lt;li&gt;
we are limited to 32 levels of hierarchy 
&lt;li&gt;
the runtime will depend on the row count that is in the table (we will need to run
on each of the rows one at the time) 
&lt;li&gt;
the run on the node will look like this :&lt;br&gt;
&lt;img height=200 alt=heirarchy.jpg src="http://www.krokhmal.com/Blog/content/binary/heirarchy.jpg" width=300 border=0&gt;
&lt;br&gt;
&lt;br&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
by the way, the most common way that I've seen to select hierarchical structure,&lt;br&gt;
is simply by setting a join between the levels in the select query.&lt;br&gt;
for example :
&lt;/p&gt;
&lt;p&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;SELECT&lt;/span&gt; TopBoss.Name
TopBoss, Boss.Name Boss, Employees.Name Employee&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;FROM&lt;/span&gt; Employees 
&lt;br&gt;
&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; Employees &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;AS&lt;/span&gt; Boss &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;ON&lt;/span&gt; Employees.BossID=Boss.EmployeeID&lt;br&gt;
&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; Employees
TopBoss &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;ON&lt;/span&gt; Boss.BossID=TopBoss.EmployeeID&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
this apply to the selection of three levels
&lt;/p&gt;
&lt;p&gt;
For each level, you'd need to join the table to itself...not an attractive option
if you have 5 or more levels ,&lt;br&gt;
you don't know how many levels you will have to select, there is no way can control
it!&lt;br&gt;
It would be great if it could join itself as many times as needed. This is called
a recursive join, and though some database products support it (Oracle has the CONNECT
BY syntax) SQL Server is not one of them.
&lt;/p&gt;
&lt;p&gt;
the other way is based on a thread that i read &lt;a href="http://www.sqlteam.com/Forums/topic.asp?TOPIC_ID=2828"&gt;here&lt;/a&gt;&amp;nbsp;about
hierarchies,&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
lets create a table :&lt;br&gt;
&lt;/p&gt;
&lt;p&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; Tree
(&lt;br&gt;
Node &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: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;NOT&lt;/span&gt; &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: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;IDENTITY&lt;/span&gt;(100,
1),&lt;br&gt;
ParentNode &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt;, 
&lt;br&gt;
EmployeeID &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: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;NOT&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;NULL&lt;/span&gt;, 
&lt;br&gt;
Depth &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;tinyint&lt;/span&gt;,&lt;br&gt;
Lineage &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;varchar&lt;/span&gt;(255)
)&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
the extra fields that has been added are the "&lt;strong&gt;lineage&lt;/strong&gt;" and the "&lt;strong&gt;depth&lt;/strong&gt;"
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Depth - for saving the current depth of the record in the hierarchy 
&lt;li&gt;
Lineage - for saving all the ancestors of the record as a concatenated string&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
after filling the needed data for relations, the table looks like this :
&lt;/p&gt;
&lt;p&gt;
&lt;table cellspacing=0 cellpadding=2 border=1&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class=head&gt;
Node&lt;/td&gt;
&lt;td class=head&gt;
ParentNode&lt;/td&gt;
&lt;td class=head&gt;
EmployeeID&lt;/td&gt;
&lt;td class=head&gt;
Depth&lt;/td&gt;
&lt;td class=head&gt;
Lineage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=n&gt;
100&lt;/td&gt;
&lt;td class=n&gt;
NULL&lt;/td&gt;
&lt;td class=n&gt;
1001&lt;/td&gt;
&lt;td class=n&gt;
NULL&lt;/td&gt;
&lt;td class=n&gt;
NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=n&gt;
101&lt;/td&gt;
&lt;td class=n&gt;
100&lt;/td&gt;
&lt;td class=n&gt;
1002&lt;/td&gt;
&lt;td class=n&gt;
NULL&lt;/td&gt;
&lt;td class=n&gt;
NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=n&gt;
102&lt;/td&gt;
&lt;td class=n&gt;
101&lt;/td&gt;
&lt;td class=n&gt;
1003&lt;/td&gt;
&lt;td class=n&gt;
NULL&lt;/td&gt;
&lt;td class=n&gt;
NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=n&gt;
103&lt;/td&gt;
&lt;td class=n&gt;
102&lt;/td&gt;
&lt;td class=n&gt;
1004&lt;/td&gt;
&lt;td class=n&gt;
NULL&lt;/td&gt;
&lt;td class=n&gt;
NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=n&gt;
104&lt;/td&gt;
&lt;td class=n&gt;
102&lt;/td&gt;
&lt;td class=n&gt;
1005&lt;/td&gt;
&lt;td class=n&gt;
NULL&lt;/td&gt;
&lt;td class=n&gt;
NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=n&gt;
105&lt;/td&gt;
&lt;td class=n&gt;
102&lt;/td&gt;
&lt;td class=n&gt;
1006&lt;/td&gt;
&lt;td class=n&gt;
NULL&lt;/td&gt;
&lt;td class=n&gt;
NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p&gt;
The next part is to find the root node of the tree, also known as the top-level, etc. 
&lt;br&gt;
That's the node that has no parent (Null), so we will start there and set the Lineage
column as the root: 
&lt;p&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;UPDATE&lt;/span&gt; Tree &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;SET&lt;/span&gt; Lineage=&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;'/'&lt;/span&gt;,
Depth=0 &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;WHERE&lt;/span&gt; ParentNode &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;Is&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;Null&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Once we did that, 
&lt;br&gt;
we can then update the rows who are the&amp;nbsp;descendant of the root node:
&lt;/p&gt;
&lt;p&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;WHILE&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;EXISTS&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; Tree &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;WHERE&lt;/span&gt; Depth &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;Is&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;Null&lt;/span&gt;)&amp;nbsp;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;UPDATE&lt;/span&gt; T &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;SET&lt;/span&gt; T.depth
= P.Depth + 1,&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;T.Lineage = P.Lineage + &lt;span style="FONT-SIZE: 11px; COLOR: fuchsia; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;Ltrim&lt;/span&gt;(&lt;span style="FONT-SIZE: 11px; COLOR: fuchsia; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;Str&lt;/span&gt;(T.ParentNode,6,0))
+ &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;'/'&lt;/span&gt;&amp;nbsp;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;FROM&lt;/span&gt; Tree &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;AS&lt;/span&gt; T&amp;nbsp;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;INNER&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;JOIN&lt;/span&gt; Tree &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;AS&lt;/span&gt; P &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;ON&lt;/span&gt; (T.ParentNode=P.Node)&amp;nbsp;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;WHERE&lt;/span&gt; P.Depth&amp;gt;=0&amp;nbsp;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;AND&lt;/span&gt; P.Lineage &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;Is&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;Not&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;Null&lt;/span&gt;&amp;nbsp;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;AND&lt;/span&gt; T.Depth &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;Is&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;Null&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font face=Verdana color=#003300 size=2&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font face=Verdana color=#003300 size=2&gt;this
loop will run once for each level of the hierarchy (&lt;strong&gt;not for each node as the
recursion method&lt;/strong&gt;.) 
&lt;br&gt;
so, with data representation of 10,000 records with 8 levels of hierarchy, 
&lt;br&gt;
this code will run only 8 times to populate the needed data of the "lineage" field
and the "depth" field, and this "heavy" procedure will happen only once at the setup.&lt;br&gt;
the table should look like this after the given operation : 
&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font face=Verdana color=#003300 size=2&gt;
&lt;br&gt;
&lt;/p&gt;
&gt;&gt;&gt; 
&lt;table cellspacing=0 cellpadding=2 border=1&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class=head&gt;
Node&lt;/td&gt;
&lt;td class=head&gt;
ParentNode&lt;/td&gt;
&lt;td class=head&gt;
EmployeeID&lt;/td&gt;
&lt;td class=head&gt;
Depth&lt;/td&gt;
&lt;td class=head&gt;
Lineage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=n&gt;
100&lt;/td&gt;
&lt;td class=n&gt;
NULL&lt;/td&gt;
&lt;td class=n&gt;
1001&lt;/td&gt;
&lt;td class=n&gt;
0&lt;/td&gt;
&lt;td class=n&gt;
/&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=n&gt;
101&lt;/td&gt;
&lt;td class=n&gt;
100&lt;/td&gt;
&lt;td class=n&gt;
1002&lt;/td&gt;
&lt;td class=n&gt;
1&lt;/td&gt;
&lt;td class=n&gt;
/100/&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=n&gt;
102&lt;/td&gt;
&lt;td class=n&gt;
101&lt;/td&gt;
&lt;td class=n&gt;
1003&lt;/td&gt;
&lt;td class=n&gt;
2&lt;/td&gt;
&lt;td class=n&gt;
/100/101/&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=n&gt;
103&lt;/td&gt;
&lt;td class=n&gt;
102&lt;/td&gt;
&lt;td class=n&gt;
1004&lt;/td&gt;
&lt;td class=n&gt;
3&lt;/td&gt;
&lt;td class=n&gt;
/100/101/102/&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=n&gt;
104&lt;/td&gt;
&lt;td class=n&gt;
102&lt;/td&gt;
&lt;td class=n&gt;
1005&lt;/td&gt;
&lt;td class=n&gt;
3&lt;/td&gt;
&lt;td class=n&gt;
/100/101/102/&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=n&gt;
105&lt;/td&gt;
&lt;td class=n&gt;
102&lt;/td&gt;
&lt;td class=n&gt;
1006&lt;/td&gt;
&lt;td class=n&gt;
3&lt;/td&gt;
&lt;td class=n&gt;
/100/101/102/&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
You'll notice that for each node, the entire lineage back to the root is stored. This
means that finding someone's boss, or their boss' boss, doesn't require any self-joins
or recursion to create an indented list. In fact, it can be accomplished with a single
SELECT.
&lt;/p&gt;
&lt;p&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;SELECT&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: fuchsia; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;Space&lt;/span&gt;(T.Depth*2)
+ E.Name &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;AS&lt;/span&gt; Name&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;FROM&lt;/span&gt; Employees
E 
&lt;br&gt;
&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; Tree
T &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;ON&lt;/span&gt; E.EmployeeID=T.EmployeeID&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;ORDER&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;BY&lt;/span&gt; T.Lineage
+ &lt;span style="FONT-SIZE: 11px; COLOR: fuchsia; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;Ltrim&lt;/span&gt;(&lt;span style="FONT-SIZE: 11px; COLOR: fuchsia; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;Str&lt;/span&gt;(T.Node,6,0))&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
maintaining the table is really not a big deal if we will use triggers.&lt;br&gt;
think about the new inserted record as the row that has not been filled in the setup
process.&lt;br&gt;
so the insert trigger should be : 
&lt;br&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;p&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;UPDATE&lt;/span&gt; T &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;SET&lt;/span&gt; T.depth
= P.Depth + 1, 
&lt;br&gt;
T.Lineage = P.Lineage + &lt;span style="FONT-SIZE: 11px; COLOR: fuchsia; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;Ltrim&lt;/span&gt;(&lt;span style="FONT-SIZE: 11px; COLOR: fuchsia; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;Str&lt;/span&gt;(T.ParentNode,6,0))
+ &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;'/'&lt;/span&gt; 
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;FROM&lt;/span&gt; Tree &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;AS&lt;/span&gt; T 
&lt;br&gt;
&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; Tree &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;AS&lt;/span&gt; P &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;ON&lt;/span&gt; (T.ParentNode=P.Node) 
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;WHERE&lt;/span&gt; P.Depth&amp;gt;=0 
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;AND&lt;/span&gt; P.Lineage &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;Is&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;Not&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;Null&lt;/span&gt; 
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;AND&lt;/span&gt; T.Depth &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;Is&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: silver; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;Null&lt;/span&gt;
&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
the update trigger should do pretty much the same : building the 2 extra field all
over again.
&lt;/p&gt;
&lt;p&gt;
suggestions and request will be repplied :)
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.krokhmal.com/aggbug.ashx?id=8d51eb7c-3975-4fcf-a2e8-75c8b1443661" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Shimon krokhmal, a part of the Krokhmal family</description>
      <comments>http://www.krokhmal.com/CommentView,guid,8d51eb7c-3975-4fcf-a2e8-75c8b1443661.aspx</comments>
      <category> Sql Server </category>
      <category>Architectural solutions</category>
      <category>database</category>
      <category>Sql Server 2000</category>
    </item>
  </channel>
</rss>