473,503 Members | 12,516 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Query to determine existence of infinate recursion in Access 2003

I have a table with two columns, one named master, the other slave.
Each column has a set of numbers. A number in one column can appear in
the other. I am trying to see if there is any infinite recursion in the
table.

E.g.:

Master Slave
1 2
2 1

Would be a simple example of infinite recursion in this context. This I
can easily detect with a simple self-join. However:

Master Slave
1 2
2 3
3 1

Is a bit harder. Of course the chain can be much longer. I am not as
concerned about the time for the query to work as I am with the accuracy
thereof. My readings on queries and infinite recursion have left me a
bit discouraged.

I don't believe I need the code spelled out for me as much as a pointer
or two.

Thanks.
Mar 27 '06 #1
8 1813
No bother <do**@email.me> wrote in
news:sR***************@fe08.lga:
I have a table with two columns, one named master, the other
slave. Each column has a set of numbers. A number in one
column can appear in the other. I am trying to see if there is
any infinite recursion in the table.

E.g.:

Master Slave
1 2
2 1

Would be a simple example of infinite recursion in this
context. This I can easily detect with a simple self-join.
However:

Master Slave
1 2
2 3
3 1

Is a bit harder. Of course the chain can be much longer. I
am not as concerned about the time for the query to work as I
am with the accuracy thereof. My readings on queries and
infinite recursion have left me a bit discouraged.

I don't believe I need the code spelled out for me as much as
a pointer or two.

Thanks.


I coded a BOM explosion module that took an array of recordsets
whch held the slave items for the current master. if the slave
wa a master, increment the array index and load the new
recordset with the slaves of the now master.

Each time you increment the child level, loop through the
array's master field, to see if the new slave is already there.
If it is there you have infinite recursion.

basically:
Dim childs(99) as recordset
Dim pointer as integer

getchilds 1,0

getchilds ( master as integer, level as integer)
childs(level)= currentdb.openrecordset("select slave from table
Where `Master = " & master & ",dbopensnapshot)
with childs(level)
do until .eof
'check for recursion
for pointer = level to 0 step -1
if childs(pointer).master = .slave then
msgbox "We have recursion"
'back out of the loop
end if
next
getchilds slave, (level +1)
loop
end with
childs(level).close
end sub

Ill try to post some of the real code tomorrow from the office.

--
Bob Quintal

PA is y I've altered my email address.
Mar 28 '06 #2
No bother <do**@email.me> wrote:
I have a table with two columns, one named master, the other slave.
Each column has a set of numbers. A number in one column can appear in
the other. I am trying to see if there is any infinite recursion in the
table.

E.g.:

Master Slave
1 2
2 1

Would be a simple example of infinite recursion in this context. This I
can easily detect with a simple self-join. However:

Master Slave
1 2
2 3
3 1

Is a bit harder. Of course the chain can be much longer. I am not as
concerned about the time for the query to work as I am with the accuracy
thereof. My readings on queries and infinite recursion have left me a
bit discouraged.

I don't believe I need the code spelled out for me as much as a pointer
or two.

Thanks.


I don't know if you can solve this problem in general with a query. If
you want to check out, google for "CELKO trees BOM" (BOM = Bill of
Materials).

If you want to use code, google for "directed graph strongly connected
component" or "Kosaraju's algorithm".

HTH
Matthias Kläy
--
www.kcc.ch

----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
Mar 28 '06 #3
No bother <do**@email.me> wrote in news:sR***************@fe08.lga:
I have a table with two columns, one named master, the other slave.
Each column has a set of numbers. A number in one column can appear in
the other. I am trying to see if there is any infinite recursion in the
table.


I'd start with something like this. I haven't tested it extensively and
don't know it it will always succeed. I'm not sure about a lot of things.
Would it be faster if the data is loaded into an array? Don't know. If I
were serious about it I would probably use some language which had sparse
arrays, that it where all the elements don't have to contain something
(without any memory being reserved for those empty elements).

Public Sub FindRecursives()
Dim r As ADODB.Recordset
Set r = CurrentProject.Connection.Execute( _
"SELECT Master, Slave, " _
& "IsRecursive(Master, Master) FROM MasterSlave")
Debug.Print
With r
While Not .EOF
Debug.Print .Fields(0).Value, _
.Fields(1).Value, _
CBool(.Fields(2).Value)
.MoveNext
Wend
End With
End Sub

Public Function IsRecursive(Master As Long, Optional Begin As Long) As
Boolean
Static Iterations As Long
Static MaximumIterations As Long
Static Start As Long
If Begin = Master Then
Iterations = 0
MaximumIterations = CurrentProject.Connection.Execute( _
"SELECT COUNT(*) FROM MasterSlave") _
.Fields(0).Value
Start = Master
End If
If Iterations > MaximumIterations Then Exit Function
Master = CurrentProject.Connection.Execute( _
"SELECT Slave FROM MasterSlave " _
& "WHERE Master = " & Master).Fields(0).Value
If Master = Start Then
IsRecursive = True
Else
Iterations = Iterations + 1
IsRecursive = IsRecursive(Master)
End If
End Function

Three runs on slightly different data are given here:
---
1 2 True
2 3 True
3 1 True
---
1 2 True
2 3 True
3 1 True
4 3 False
---
1 3 True
2 3 False
3 1 True
4 3 False

When would this finish for 100 000 records? Probably not in my lifetime.

Interesting Problem. Thanks for sharing it.

And yes, one could use DAO just as well.

--
Lyle Fairfield
Mar 28 '06 #4
Thanks for the help!

I ended up making a little change from:
Master = CurrentProject.Connection.Execute( _
"SELECT Slave FROM MasterSlave " _
& "WHERE Master = " & Master).Fields(0).Value
to
dim r as recordset
r = CurrentProject.Connection.Execute( _
"SELECT Slave FROM MasterSlave " _
& "WHERE Master = " & Master)
if r.recordcount > 0 then
master = r.fields(0).value
....

I also converted this to DAO, but I won't bore the group with the details.

I also found that when executing this that after about five minutes I
would get a message complaining about not being able to open more
databases. I may try again when:
1. I get access (no pun intended) to a Cray or a big iron
2. Access is ported to one of these, either when XP is ported or Access
is ported directly to an OS that runs on one of these

I'm not holding my breath.

On the other hand, maybe Cobol would be up to the task...
Lyle Fairfield wrote:
No bother <do**@email.me> wrote in news:sR***************@fe08.lga:
I have a table with two columns, one named master, the other slave.
Each column has a set of numbers. A number in one column can appear in
the other. I am trying to see if there is any infinite recursion in the
table.


I'd start with something like this. I haven't tested it extensively and
don't know it it will always succeed. I'm not sure about a lot of things.
Would it be faster if the data is loaded into an array? Don't know. If I
were serious about it I would probably use some language which had sparse
arrays, that it where all the elements don't have to contain something
(without any memory being reserved for those empty elements).

Public Sub FindRecursives()
Dim r As ADODB.Recordset
Set r = CurrentProject.Connection.Execute( _
"SELECT Master, Slave, " _
& "IsRecursive(Master, Master) FROM MasterSlave")
Debug.Print
With r
While Not .EOF
Debug.Print .Fields(0).Value, _
.Fields(1).Value, _
CBool(.Fields(2).Value)
.MoveNext
Wend
End With
End Sub

Public Function IsRecursive(Master As Long, Optional Begin As Long) As
Boolean
Static Iterations As Long
Static MaximumIterations As Long
Static Start As Long
If Begin = Master Then
Iterations = 0
MaximumIterations = CurrentProject.Connection.Execute( _
"SELECT COUNT(*) FROM MasterSlave") _
.Fields(0).Value
Start = Master
End If
If Iterations > MaximumIterations Then Exit Function
Master = CurrentProject.Connection.Execute( _
"SELECT Slave FROM MasterSlave " _
& "WHERE Master = " & Master).Fields(0).Value
If Master = Start Then
IsRecursive = True
Else
Iterations = Iterations + 1
IsRecursive = IsRecursive(Master)
End If
End Function

Three runs on slightly different data are given here:
---
1 2 True
2 3 True
3 1 True
---
1 2 True
2 3 True
3 1 True
4 3 False
---
1 3 True
2 3 False
3 1 True
4 3 False

When would this finish for 100 000 records? Probably not in my lifetime.

Interesting Problem. Thanks for sharing it.

And yes, one could use DAO just as well.

Mar 30 '06 #5
No bother <do**@email.me> wrote in news:iq************@fe10.lga:
Thanks for the help!

I ended up making a little change from:
Master = CurrentProject.Connection.Execute( _
"SELECT Slave FROM MasterSlave " _
& "WHERE Master = " & Master).Fields(0).Value
to
dim r as recordset
r = CurrentProject.Connection.Execute( _
"SELECT Slave FROM MasterSlave " _
& "WHERE Master = " & Master)
if r.recordcount > 0 then
master = r.fields(0).value
...

I also converted this to DAO, but I won't bore the group with the
details.

I also found that when executing this that after about five minutes I
would get a message complaining about not being able to open more
databases.


I wonder if ADO uses enough of JET and DAO that it too opens Databases?
Perhaps it does not.

If both DAO and ADO open too many databases then one could pretty easily
map the recordset to an array and do the recursion with it. Probably I
would want to do this with some language which allowed for sparse arrays.
VBA isn't it.

Of course, like everything, too many records would be too much.
Mar 30 '06 #6
"No bother" <do**@email.me> schreef in bericht
news:sR***************@fe08.lga...
I don't believe I need the code spelled out for me as much as a pointer or
two.


If the recursive version is impracatical, you may try the
traditional iterative way of proving a graph is acyclic, basically:

1. count the number of masters for each node
2. remove all nodes with count = 0
3. decrement count for each slave of each removed node
4. repeat from 2. until al nodes are removed (graph is acyclic)
or no node has count = 0 (graph has at least one cycle)

--
Paul

Mar 30 '06 #7
Kaniest schreef:
If the recursive version is impracatical, you may try the
traditional iterative way of proving a graph is acyclic, basically:

1. count the number of masters for each node
2. remove all nodes with count = 0
3. decrement count for each slave of each removed node
4. repeat from 2. until al nodes are removed (graph is acyclic)
or no node has count = 0 (graph has at least one cycle)


For nitpickers: of course this applies to directed graphs.
Mar 30 '06 #8
No bother wrote:
On the other hand, maybe Cobol would be up to the task...


This approach works nicely in Cobol (VBA/DAO version):

'Check the graph in table or query Arrows(tail,head) for cycles
'strategy: remove sinks (work head to tail)
With CurrentDb 'use temp table H1(head)

'make H1 the subset of distinct tails
.Execute _
"SELECT DISTINCT tail AS head INTO H1 FROM Arrows;"

Do While .RecordsAffected
'remove sinks from subgraph A1 with heads in H1
#If Not JET_antics Then
.Execute _
"DELETE * FROM H1 WHERE head NOT IN " & _
"(SELECT tail FROM Arrows WHERE head IN " & _
"(SELECT head FROM H1));"
#Else
.Execute _
"DELETE DISTINCTROW H1.* FROM H1 LEFT JOIN " & _
"[SELECT tail FROM Arrows INNER JOIN " & _
"H1 ON Arrows.head = H1.head]. AS T1 ON H1.head = T1.tail " & _
"WHERE tail Is Null;"
#End If
Loop
'leaves subgraph A1 without sinks (empty or having cycles)

Debug.Print "Cycle(s) present:"; .TableDefs!H1.RecordCount > 0

.Execute _
"DROP TABLE H1;"
End With
Apr 3 '06 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
1885
by: Steven D.Arnold | last post by:
I have a query which does not use column indexes that it should use. I have discovered some interesting behaviors of Postgres which may indicate a bug in the database's query planning. Take a...
10
2955
by: Kenneth | last post by:
I have a Query that consist of a lot of different sales data, and one of the colums are different date. The date goes from 1jan2003 til 31jan2003. in this Query I only want the salesdata for...
2
1850
by: Jerry | last post by:
Hi, Access 2003. I would like to query specific dates or years. I need to be able to selct the dates in a query, ie aug 12 2004, aug 11th 2004, or 2001, 2002 and 2003. Any help is most appreciated
11
3441
by: Bradford Chamberlain | last post by:
I work a lot with multidimensional arrays of dynamic size in C, implementing them using a single-dimensional C array and the appropriate multipliers and offsets to index into it appropriately. I...
4
2053
by: d.p. | last post by:
Hi all, I'm using MS Access 2003. Bare with me on this description....here's the situation: Imagine insurance, and working out premiums for different insured properties. The rates for calculating...
4
7134
by: Br | last post by:
We're using an Access2000 ADP with an SQL2000 back-end. Because SQL2000 was released after Access2000 you need to be running Access2000 SP1 (2 or 3) for it to work properly. Is there an easy way...
13
3217
by: Rick | last post by:
The following code will enter an infinate loop when in ReadChars. I can only make it happen when reading a Stream and with this particular XML. If I use the ReadInnerXml call rather than my own...
22
31147
by: Stan | last post by:
I am working with Access 2003 on a computer running XP. I am new at using Access. I have a Db with a date field stored as mm/dd/yyyy. I need a Query that will prompt for the month, ie. 6 for...
11
2622
by: lenygold via DBMonster.com | last post by:
Hi everybody! This query is supposed to count consecutive years from the current year without OLAP. Input Table: ID DateCol 1 02/01/2006 1 01/01/2006 1 01/01/2005
0
7212
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7098
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7470
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
5604
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
4696
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3186
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
1524
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
751
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
405
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.