Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
X002548
Not Just a Number
15586 Posts |
Posted - 2010-10-11 : 14:47:09
|
Someone must have written this already...trying to find a CTE that uses recursion to produce a list of FK's in hierarchal orderWITH FK_TREE(TABLE_ID, TABLE_FK, PARENT_ID, PARENT_FK, FK_LEVEL)AS (SELECT [parent_object_id] AS TABLE_ID , OBJECT_NAME([parent_object_id]) AS TABLE_FK , [referenced_object_id] AS PARENT_ID , OBJECT_NAME([referenced_object_id]) AS PARENT_FK , 0 AS FK_LEVEL FROM sys.foreign_keys WHERE [type] = 'F' AND [parent_object_id] NOT IN (SELECT [referenced_object_id] FROM sys.foreign_keys)UNION ALLSELECT l.[parent_object_id] AS TABLE_ID , OBJECT_NAME(l.[parent_object_id]) AS TABLE_FK , l.[referenced_object_id] AS PARENT_ID , OBJECT_NAME(l.[referenced_object_id]) AS PARENT_FK , r.FK_LEVEL + 1 FROM sys.foreign_keys l INNER JOIN FK_TREE r ON l.[referenced_object_id] = r.PARENT_ID WHERE l.[type] = 'F' )SELECT * FROM FK_TREEORDER BY FK_LEVEL, TABLE_FK Brett8-)Hint: Want your questions answered fast? Follow the direction in this linkhttp://weblogs.sqlteam.com/brettk/archive/2005/05/25/5276.aspxWant to help yourself?http://msdn.microsoft.com/en-us/library/ms130214.aspx |
|
|
X002548
Not Just a Number
15586 Posts |
Posted - 2010-10-11 : 15:05:04
|
OK,Found thishttp://stackoverflow.com/questions/352176/sqlserver-how-to-sort-table-names-ordered-by-their-foreign-key-dependencyBut I thought it would be much simpler...plus it doesn''t show all Tables like I wantedI modified it, and it works for me, but I still think this should be pretty simpleWITH AllTables(TableName) AS ( SELECT OBJECT_SCHEMA_NAME(so.id) +'.'+ OBJECT_NAME(so.id) FROM dbo.sysobjects so INNER JOIN sys.all_columns ac ON so.ID = ac.object_id WHERE so.type = 'U' AND ac.is_rowguidcol = 1 ), Relationships(ReferenceTableName, ReferenceColumnName, TableName, ColumnName) AS ( SELECT OBJECT_SCHEMA_NAME (fkey.referenced_object_id) + '.' + OBJECT_NAME (fkey.referenced_object_id) AS ReferenceTableName ,COL_NAME(fcol.referenced_object_id, fcol.referenced_column_id) AS ReferenceColumnName ,OBJECT_SCHEMA_NAME (fkey.parent_object_id) + '.' + OBJECT_NAME(fkey.parent_object_id) AS TableName ,COL_NAME(fcol.parent_object_id, fcol.parent_column_id) AS ColumnName FROM sys.foreign_keys AS fkey INNER JOIN sys.foreign_key_columns AS fcol ON fkey.OBJECT_ID = fcol.constraint_object_id ), NotReferencedOrReferencing(TableName) AS ( SELECT TableName FROM AllTables EXCEPT SELECT TableName FROM Relationships EXCEPT SELECT ReferenceTableName FROM Relationships ), OnlyReferenced(Tablename) AS ( SELECT ReferenceTableName FROM Relationships EXCEPT SELECT TableName FROM Relationships ), -- These need to be sorted based on theire internal relationships ReferencedAndReferencing(TableName, ReferenceTableName) AS ( SELECT r1.Tablename, r2.ReferenceTableName FROM Relationships r1 INNER JOIN Relationships r2 ON r1.TableName = r2.ReferenceTableName ), OnlyReferencing(TableName) AS ( SELECT Tablename FROM Relationships EXCEPT SELECT ReferenceTablename FROM Relationships ) SELECT TableName, SORTING FROM (SELECT TableName, 1000 AS Sorting FROM NotReferencedOrReferencing UNION SELECT TableName, 2000 AS Sorting FROM OnlyReferenced UNION SELECT TableName, 3000 AS Sorting FROM ReferencedAndReferencing UNION SELECT TableName, 4000 AS Sorting FROM OnlyReferencing) AS XXXUNIONSELECT TABLE_NAME, 9999 AS SORTINGFROM INFORMATION_SCHEMA.COLUMNSWHERE TABLE_NAME NOT IN (SELECT TableName FROM NotReferencedOrReferencing UNION SELECT TableName FROM OnlyReferenced UNION SELECT TableName FROM ReferencedAndReferencing UNION SELECT TableName FROM OnlyReferencing)ORDER BY Sorting DESC , TABLE_NAME Brett8-)Hint: Want your questions answered fast? Follow the direction in this linkhttp://weblogs.sqlteam.com/brettk/archive/2005/05/25/5276.aspxWant to help yourself?http://msdn.microsoft.com/en-us/library/ms130214.aspx |
 |
|
|
X002548
Not Just a Number
15586 Posts |
|
|
X002548
Not Just a Number
15586 Posts |
Posted - 2010-10-11 : 15:18:49
|
Some enhancements..should trun this into a sproc or udfIF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[FK_TREE]') AND type in (N'U'))DROP TABLE [dbo].[FK_TREE]GOCREATE TABLE [dbo].[FK_TREE]( [TABLE_NAME] [varchar](255) , [FK_LEVEL] [int])GOWITH AllTables(TableName) AS ( SELECT OBJECT_SCHEMA_NAME(so.id) +'.'+ OBJECT_NAME(so.id) FROM dbo.sysobjects so INNER JOIN sys.all_columns ac ON so.ID = ac.object_id WHERE so.type = 'U' AND ac.is_rowguidcol = 1 ), Relationships(ReferenceTableName, ReferenceColumnName, TableName, ColumnName) AS ( SELECT OBJECT_SCHEMA_NAME (fkey.referenced_object_id) + '.' + OBJECT_NAME (fkey.referenced_object_id) AS ReferenceTableName ,COL_NAME(fcol.referenced_object_id, fcol.referenced_column_id) AS ReferenceColumnName ,OBJECT_SCHEMA_NAME (fkey.parent_object_id) + '.' + OBJECT_NAME(fkey.parent_object_id) AS TableName ,COL_NAME(fcol.parent_object_id, fcol.parent_column_id) AS ColumnName FROM sys.foreign_keys AS fkey INNER JOIN sys.foreign_key_columns AS fcol ON fkey.OBJECT_ID = fcol.constraint_object_id ), NotReferencedOrReferencing(TableName) AS ( SELECT TableName FROM AllTables EXCEPT SELECT TableName FROM Relationships EXCEPT SELECT ReferenceTableName FROM Relationships ), OnlyReferenced(Tablename) AS ( SELECT ReferenceTableName FROM Relationships EXCEPT SELECT TableName FROM Relationships ), -- These need to be sorted based on theire internal relationships ReferencedAndReferencing(TableName, ReferenceTableName) AS ( SELECT r1.Tablename, r2.ReferenceTableName FROM Relationships r1 INNER JOIN Relationships r2 ON r1.TableName = r2.ReferenceTableName ), OnlyReferencing(TableName) AS ( SELECT Tablename FROM Relationships EXCEPT SELECT ReferenceTablename FROM Relationships ) INSERT INTO FK_TREE (TABLE_NAME, FK_LEVEL)SELECT TableName, SORTING FROM (SELECT TableName, 1000 AS Sorting FROM NotReferencedOrReferencing UNION SELECT TableName, 2000 AS Sorting FROM OnlyReferenced UNION SELECT TableName, 3000 AS Sorting FROM ReferencedAndReferencing UNION SELECT TableName, 4000 AS Sorting FROM OnlyReferencing) AS XXXUNIONSELECT TABLE_SCHEMA + '.' + TABLE_NAME, 9999 AS SORTINGFROM INFORMATION_SCHEMA.COLUMNSWHERE TABLE_SCHEMA + '.' + TABLE_NAME NOT IN (SELECT TableName FROM NotReferencedOrReferencing UNION SELECT TableName FROM OnlyReferenced UNION SELECT TableName FROM ReferencedAndReferencing UNION SELECT TableName FROM OnlyReferencing)ORDER BY Sorting DESC , 1SELECT * FROM FK_TREE Brett8-)Hint: Want your questions answered fast? Follow the direction in this linkhttp://weblogs.sqlteam.com/brettk/archive/2005/05/25/5276.aspxWant to help yourself?http://msdn.microsoft.com/en-us/library/ms130214.aspx |
 |
|
|
Michael Valentine Jones
Yak DBA Kernel (pronounced Colonel)
7020 Posts |
|
|
russell
Pyro-ma-ni-yak
5072 Posts |
Posted - 2010-10-11 : 17:55:13
|
That's a nice script.This may be what Brett is after. Note, Had to use temp table, because outer joins and table variables aren't valid inside of CTEs for the recursive partCreate Table #t ( fk_object_id int, pObjId int, parentTable sysname, cObjId int, childTable sysname, fk2_object_id int) INSERT #tSELECT fk1.object_id, fk1.referenced_object_id pObjId, object_name(fk1.referenced_object_id) parentTable, fk1.parent_object_id cObjId, object_name(fk1.parent_object_id) childTable, fk2.object_idFROM SYS.FOREIGN_KEYS fk1LEFT JOIN SYS.FOREIGN_KEYS fk2On fk1.referenced_object_id = fk2.parent_object_id;WITH FKs (fk_object_id, pObjId, parentTable, cObjId, childTable, level, sort)AS ( SELECT t.fk_object_id, t.pObjId, t.parentTable, t.cObjId, t.childTable, 1, t.parentTable FROM #t t WHERE fk2_object_id IS NULL UNION ALL SELECT t.fk_object_id, t.pObjId, t.parentTable, t.cObjId, t.childTable, level + 1, t.parentTable FROM #t t JOIN FKs On FKs.cObjId = t.pObjId)SELECT distinct pObjId, parentTable, cObjId, childTable, levelFROM FKsORDER BY parentTableDROP TABLE #t If you want it printable, you can replicate pipes and tabs like here: http://msdn.microsoft.com/en-us/library/ms175972.aspx |
 |
|
|
|
|
|
|
|