By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
438,004 Members | 1,253 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 438,004 IT Pros & Developers. It's quick & easy.

Traversing Relationship Tree

P: n/a
I am attempting to write a query that will traverse the relationships
for tables in my database that will provide me the order in which I
need to perform delete operations to avoid running into foreign key
constraints. I have determined the delete order manually, but since the
database is complex and always having to structures added to it as the
scope of the application grows, I was looking for an automated
approach.

I tried modelling the query after some recursive examples from Graeme
Birchall's SQL Cookbook, but am missing something fundamental and the
query produces "infinite" output. I have been using SYSCAT.REFERENCES
as my target table (view). The last incarnation of my query looks
something like this:

with temp1 (src_name, depends_on) as
((select root.reftabname, root.tabname
from syscat.references root
where root.reftabname='PX_CASE')
union all
( select child.reftabname, child.tabname
from temp1 parent, syscat.references child
where parent.depends_on = child.tabname)
)
select depends_on
from temp1
order by depends_on;

There are only 130 FK constraints on the collective tables, yet this
produces thousands of rows of output before I end up manually
terminating it. I have probably bitten off more than I can chew, but am
convinced that the solution exists to this problem. Can anyone make any
suggestions?

Thanks,
Mike

May 10 '06 #1
Share this Question
Share on Google+
3 Replies


P: n/a
mikelbell2000 wrote:
I am attempting to write a query that will traverse the relationships
for tables in my database that will provide me the order in which I
need to perform delete operations to avoid running into foreign key
constraints. I have determined the delete order manually, but since the
database is complex and always having to structures added to it as the
scope of the application grows, I was looking for an automated
approach.

I tried modelling the query after some recursive examples from Graeme
Birchall's SQL Cookbook, but am missing something fundamental and the
query produces "infinite" output. I have been using SYSCAT.REFERENCES
as my target table (view). The last incarnation of my query looks
something like this:

with temp1 (src_name, depends_on) as
((select root.reftabname, root.tabname
from syscat.references root
where root.reftabname='PX_CASE')
union all
( select child.reftabname, child.tabname
from temp1 parent, syscat.references child
where parent.depends_on = child.tabname)
)


Somehow this doesn't make a lot of sense to me. src_name is the name of a
referenced table A and "depends_on" contains the name of a referencing
table B (according to the start of the recursion). The part after the
UNION ALL should now try to find all tables that reference B, right? But
the sub-select there finds table B itself again. I would have expected
something like this:

WITH temp1 (src_name, depends_on) AS
( SELECT root.reftabname, root.tabname
FROM syscat.references root
WHERE root.reftabname='PX_CASE'
UNION ALL
SELECT child.reftabname, child.tabname
FROM temp1 parent, syscat.references child
WHERE parent.depends_on = child.reftabname )
SELECT depends_on
FROM temp1
ORDER BY depends_on

There are some other issues I see:
(1) You have table 'PX_CASE' as start of the recursion. You'll only find
tables that refer directly or indirectly to that one. If there are other
"start tables", you may miss things.
(2) You should add an explicit termination criteria (see examples in the SQL
Reference) to prevent endless recursions due to circular dependencies or
self-referencing tables.
(3) I would probably start at the leafs of the dependency-tree/graph, i.e.
with the tables that are not referenced by any other.

--
Knut Stolze
DB2 Information Integration Development
IBM Germany
May 10 '06 #2

P: n/a
Thanks, Knut. This works much better. I usually shun recursion because
it's one of those things that makes my brain hurt when I think about it
too deeply :-)

The query I posted was probably the 10th incarnation of my attempt to
do this.

The first issue you raised is dead on. This is exactly what I want in
my particular case. I am actually looking to for all tables that are
descendants of one particular master table. My exact scenario is for
every record in PX_CASE that is older than a certain date, I want to
move it and all its dependents out of the current database into an
"archive" database. I build a list of all cases then use the table list
(which would be generated the recursive query) to export all related
data.

After loading data into archive database I need to delete from the
primary database. I need to delete from the bottom up.I will take your
version of the query and try to tweak it to include depth information
to be give me the delete order.

Cheers,
Mike

May 10 '06 #3

P: n/a
mikelbell2000 wrote:
Thanks, Knut. This works much better. I usually shun recursion because
it's one of those things that makes my brain hurt when I think about it
too deeply :-)

The query I posted was probably the 10th incarnation of my attempt to
do this.

The first issue you raised is dead on. This is exactly what I want in
my particular case. I am actually looking to for all tables that are
descendants of one particular master table. My exact scenario is for
every record in PX_CASE that is older than a certain date, I want to
move it and all its dependents out of the current database into an
"archive" database. I build a list of all cases then use the table list
(which would be generated the recursive query) to export all related
data.

After loading data into archive database I need to delete from the
primary database. I need to delete from the bottom up.I will take your
version of the query and try to tweak it to include depth information
to be give me the delete order.


Great, archiving. I did something along those lines in my master's
thesis. ;-)

--
Knut Stolze
DB2 Information Integration Development
IBM Germany
May 12 '06 #4

This discussion thread is closed

Replies have been disabled for this discussion.