1

I have this script to return all child and grandchildren tables with their level from a database . How do I change this if I only want to return the child and grandchildren tables of a particular table .

;WITH dependencies -- Get sp with  dependencies
AS (
    SELECT 
        DISTINCT procs.NAME AS Tablename 
                   ,OBJDEP.NAME as Depends 
                   ,sch.name as schemaname
    FROM    sysforeignkeys a
        INNER JOIN sysobjects OBJ ON a.fkeyid = OBJ.id
        INNER JOIN sysobjects OBJDEP ON a.rkeyid = OBJDEP.id
        inner join   sys.objects procs  on a.fkeyid = procs.object_id
        inner join sys.schemas sch on sch.schema_id=procs.schema_id
    where obj.type='U'
    and OBJDEP.type='u'
    ), 
no_dependencies 
AS (
    SELECT   
        obj.NAME AS Tablename
        ,sch.name as schemaname
     FROM sys.objects OBJ
     INNER JOIN sys.schemas sch on sch.schema_id=obj.schema_id
     WHERE  NOT EXISTS (
        SELECT 1 
        FROM dependencies k 
        where obj.name=k.Tablename 
        and sch.name=k.schemaname) and type='u'
    
    ), 
recursiv -- recursive CTE to get dependencies
AS (
    SELECT Tablename AS [SP]
        , CAST('' AS VARCHAR(max)) AS DependsON
        , 0 AS LVL 
        ,schemaname
    FROM no_dependencies
    UNION ALL
    SELECT d.Tablename AS [SP]
         ,CAST( d.Depends AS VARCHAR(max))
         ,R.lvl + 1 AS LVL
         ,d.schemaname
    FROM dependencies d
    INNER JOIN recursiv r
        ON d.Depends = r.[SP]
    )


SELECT * FROM RECURSIV  ORDER BY LVL  option (maxrecursion 0)
2
  • Which database system and version are you using?
    – J.D.
    Commented Jan 10, 2023 at 13:11
  • SQL server 2019 Commented Jan 10, 2023 at 13:13

1 Answer 1

1

You need to pass the root parent (from level 0) item through every iteration of the recursion. You can do that by having a dedicated RootParent field which you continue to pass the same value for all the way down the recursion, like so:

;WITH dependencies -- Get sp with  dependencies
AS (
    SELECT 
        DISTINCT procs.NAME AS Tablename 
                   ,OBJDEP.NAME as Depends 
                   ,sch.name as schemaname
    FROM    sysforeignkeys a
        INNER JOIN sysobjects OBJ ON a.fkeyid = OBJ.id
        INNER JOIN sysobjects OBJDEP ON a.rkeyid = OBJDEP.id
        inner join   sys.objects procs  on a.fkeyid = procs.object_id
        inner join sys.schemas sch on sch.schema_id=procs.schema_id
    where obj.type='U'
    and OBJDEP.type='u'
    ), 
no_dependencies 
AS (
    SELECT   
        obj.NAME AS Tablename
        ,sch.name as schemaname
     FROM sys.objects OBJ
     INNER JOIN sys.schemas sch on sch.schema_id=obj.schema_id
     WHERE  NOT EXISTS (
        SELECT 1 
        FROM dependencies k 
        where obj.name=k.Tablename 
        and sch.name=k.schemaname) and type='u'
    
    ), 
recursiv -- recursive CTE to get dependencies
AS (
    SELECT 
         Tablename AS RootParent,
         schemaname AS RootParentSchema,
         Tablename AS [SP]
        , CAST('' AS VARCHAR(max)) AS DependsON
        , 0 AS LVL 
        ,schemaname
    FROM no_dependencies
    UNION ALL
    SELECT 
         R.RootParent,
         R.RootParentSchema,
         d.Tablename AS [SP]
         ,CAST( d.Depends AS VARCHAR(max))
         ,R.lvl + 1 AS LVL
         ,d.schemaname
    FROM dependencies d
    INNER JOIN recursiv r
        ON d.Depends = r.[SP]
    )


SELECT * 
FROM RECURSIV
WHERE RootParent = 'TheTableName'
    --AND RootParentSchema = 'TheSchemaName' -- Optionally you'll want to filter by a specific schema too if you have different objects with the same name in different schemas. If so, you can uncomment this AND predicate.
ORDER BY LVL
option (maxrecursion 0)
7
  • That will only give that particular table and the child's , i want to return the grand child tables too. Commented Jan 11, 2023 at 2:14
  • @SubinBenny Sorry I fixed it now. Please see my updated answer.
    – J.D.
    Commented Jan 11, 2023 at 2:23
  • Thanks for the effort JD. It works fine if i give the root parent , but I need to to return the grandchildren tables if I give a child table as root parent . Which doesn't work . Suppose table a->b->c-> this is the tree. If I give a as the table name then this will work . But if I give b as the table then nothing will return. But I need to return 'c' in that case. Hope you understood it. @J.D. Commented Jan 11, 2023 at 14:38
  • @SubinBenny Hi, I understand what you're looking for. It should accomplish that, because b should be the root parent of a subtree in a further level of the recursion (usually), in a normal tree structure relation. But I haven't tested this query, and I suspect it has to do with how the data is setup in the objects being queried. I will have to test and see where it's missing.
    – J.D.
    Commented Jan 11, 2023 at 20:21
  • Thank you ! J.D. Commented Jan 12, 2023 at 3:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.