Domanda

I have a database in which tables have relationships with other tables and make a n-level hierarchy such that

Parent Table -> Child tables -> Grand-child tables and so on.

So this means that any child table of root parent table can be parent of some other tables. There can be different/multiple hierarchies of such relationships.

Now I want a query on sys objects (e.g. sys.foreign_keys etc) to retrieve all child tables against a Parent table. e.g I have following related tables

Select OBJECT_NAME(Parent.parent_object_id) ForeignKeyTable, OBJECT_NAME(Parent.referenced_object_id) PrimaryKeyTable, Parent.name 
From sys.foreign_keys Parent
LEFT JOIN sys.foreign_keys Child 
On Parent.referenced_object_id = Child.parent_object_id
Where OBJECT_NAME(Child.referenced_object_id) = 'PersonOrganisation' OR  
OBJECT_NAME(Child.parent_object_id) = 'PersonOrganisation'

PersonOrganisation -> Organisation -> Services -> ServiceAttendants

So when if I need to get all child tables of PersonOrganisation then it should return hierarchy from Organisation to ServiceAttendants

and if I want to get child tables of Organisation, it should return hierarchy from Services to ServiceAttendants

I have written a following Query. It seems fine but I just want to reconfirm or a better query approach than this.

È stato utile?

Soluzione

You could use a recursive CTE like this:

;with x as (
    select cast(object_name(parent_object_id) as varchar(max)) as name, parent_object_id, 0 as lvl
    from sys.foreign_keys
    where referenced_object_id = object_id('table_name')

    union all

    select cast(x.name + ' -> ' + object_name(f.parent_object_id) as varchar(max)), f.parent_object_id, lvl + 1
    from sys.foreign_keys f
    inner join x on x.parent_object_id = f.referenced_object_id 
    and x.parent_object_id <> f.parent_object_id
)
select name
from x
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top