|
| 1 | +/* |
| 2 | +Author: Alexandros Pappas |
| 3 | +Original link: http://www.codeproject.com/Articles/1118722/SQL-Table-Hierarchy |
| 4 | +*/ |
| 5 | + |
| 6 | +DECLARE @fkcolumns TABLE(name SYSNAME PRIMARY KEY, referencedtable SYSNAME, parenttable SYSNAME, referencedcolumns varchar(MAX), parentcolumns varchar(MAX)) |
| 7 | +INSERT @fkcolumns |
| 8 | +SELECT |
| 9 | + a.name, |
| 10 | + b.name, |
| 11 | + c.name, |
| 12 | + STUFF(( |
| 13 | + SELECT ',' + c.name |
| 14 | + FROM sys.foreign_key_columns b |
| 15 | + INNER JOIN sys.columns c ON b.referenced_object_id = c.object_id |
| 16 | + AND b.referenced_column_id = c.column_id |
| 17 | + WHERE a.object_id = b.constraint_object_id |
| 18 | + FOR XML PATH('')), 1, 1, '') parentcolumns, |
| 19 | + STUFF(( |
| 20 | + SELECT ',' + c.name |
| 21 | + FROM sys.foreign_key_columns b |
| 22 | + INNER JOIN sys.columns c ON b.parent_object_id = c.object_id |
| 23 | + AND b.parent_column_id = c.column_id |
| 24 | + WHERE a.object_id = b.constraint_object_id |
| 25 | + FOR XML PATH('')), 1, 1, '') childcolumns |
| 26 | +FROM sys.foreign_keys a |
| 27 | +INNER JOIN sys.tables b ON a.referenced_object_id = b.object_id |
| 28 | +INNER JOIN sys.tables c ON a.parent_object_id = c.object_id; |
| 29 | + |
| 30 | +DECLARE @fkrefs TABLE(referencedtable SYSNAME, parenttable SYSNAME, referencedcolumns varchar(MAX), parentcolumns varchar(MAX)) |
| 31 | +INSERT @fkrefs |
| 32 | +SELECT *, |
| 33 | + (SELECT TOP 1 b.referencedcolumns |
| 34 | + FROM @fkcolumns b |
| 35 | + WHERE a.referencedtable = b.referencedtable and a.parenttable = b.parenttable), |
| 36 | + STUFF(( |
| 37 | + SELECT ';' + b.parentcolumns |
| 38 | + FROM @fkcolumns b |
| 39 | + WHERE a.referencedtable = b.referencedtable and a.parenttable = b.parenttable |
| 40 | + FOR XML PATH('')), 1, 1, '') |
| 41 | +FROM ( |
| 42 | + SELECT referencedtable, parenttable |
| 43 | + FROM @fkcolumns a |
| 44 | + GROUP BY referencedtable, parenttable |
| 45 | +) a; |
| 46 | + |
| 47 | +WITH fks(treelevel, treepath, tablename, referencedcolumns, parentcolumns) AS ( |
| 48 | +SELECT 1, |
| 49 | + CAST(a.name AS VARCHAR(MAX)), |
| 50 | + a.name, |
| 51 | + CAST('' AS VARCHAR(MAX)), |
| 52 | + CAST('' AS VARCHAR(MAX)) |
| 53 | + FROM sys.tables a |
| 54 | + LEFT JOIN @fkrefs c ON a.name = c.parenttable AND c.referencedtable <> c.parenttable |
| 55 | + WHERE c.referencedtable IS NULL |
| 56 | + UNION ALL |
| 57 | + SELECT treelevel + 1, |
| 58 | + CAST(a.treepath + '_' + b.parenttable AS varchar(MAX)), |
| 59 | + b.parenttable, |
| 60 | + b.referencedcolumns, |
| 61 | + b.parentcolumns |
| 62 | + FROM fks a |
| 63 | + INNER JOIN @fkrefs b ON a.tablename = b.referencedtable |
| 64 | + WHERE treelevel < 10) |
| 65 | +SELECT treelevel, |
| 66 | + treepath, |
| 67 | + REPLICATE('|---- ', treelevel) + tablename tablename, |
| 68 | + referencedcolumns, |
| 69 | + parentcolumns |
| 70 | +FROM fks |
| 71 | +ORDER BY treepath; |
0 commit comments