When I call this function, everything works, as long as I don’t try to recursively call the function again. In other words if I uncomment the line:
GetChilds rsData('AcctID'), intLevel + 1
Then the function breaks.
<% Function GetChilds(ParentID, intLevel) Set rsData= Server.CreateObject('ADODB.Recordset') sSQL = 'SELECT AcctID, ParentID FROM Accounts WHERE ParentID='' & ParentID &''' rsData.Open sSQL, conDB, adOpenKeyset, adLockOptimistic If IsRSEmpty(rsData) Then Response.Write('Empty') Else Do Until rsData.EOF Response.Write rsData('AcctID') & '<br />' 'GetChilds rsData('AcctID'), intLevel + 1 rsData.MoveNext Loop End If rsData.close: set rsData = nothing End Function Call GetChilds(1,0) %>
*Edited after feedback
Thanks everyone,
Other than the usual error:
Error Type: (0x80020009) Exception occurred.
I wasn’t sure what was causing the problems. I understand that is probably due to a couple of factors.
- Not closing the connection and attempting to re-open the same connection.
- To many concurrent connections to the database.
The database content is as follows:
AcctID | ParentID 1 Null 2 1 3 1 4 2 5 2 6 3 7 4
The idea is so that I can have a Master Account with Child Accounts, and those Child Accounts can have Child Accounts of their Own. Eventually there will be Another Master Account with a ParentID of Null that will have childs of its own. With that in mind, am I going about this the correct way?
Thanks for the quick responses.
Thanks everyone,
Other than the usual error:
Error Type: (0x80020009) Exception occurred.
I wasn’t sure what was causing the problems. I understand that is probably due to a couple of factors.
- Not closing the connection and attempting to re-open the same connection.
- To many concurrent connections to the database.
The database content is as follows:
AcctID | ParentID 1 Null 2 1 3 1 4 2 5 2 6 3 7 4
The idea is so that I can have a Master Account with Child Accounts, and those Child Accounts can have Child Accounts of their Own. Eventually there will be Another Master Account with a ParentID of Null that will have childs of its own. With that in mind, am I going about this the correct way?
Thanks for the quick responses.
Look like it fails because your connection is still busy serving the RecordSet from the previous call.
One option is to use a fresh connection for each call. The danger there is that you’ll quickly run out of connections if you recurse too many times.
Another option is to read the contents of each RecordSet into a disconnected collection: (Dictionary, Array, etc) so you can close the connection right away. Then iterate over the disconnected collection.
If you’re using SQL Server 2005 or later there’s an even better option. You can use a CTE (common table expression) to write a recursive sql query. Then you can move everything to the database and you only need to execute one query.
Some other notes:
ID fields are normally
ints, so you shouldn’t encase them in ‘ characters in the sql string.Finally, this code is probably okay because I doubt the user is allowed to input an id number directly. However, the dynamic sql technique used is very dangerous and should generally be avoided. Use query parameters instead to prevent sql injection.
I’m not too worried about not using
intLevelfor anything. Looking at the code this is obviously an early version, and intLevel can be used later to determine something like indentation or the class name used when styling an element.