下面的SQL根据表之间的关系分隔表.问题出在3000系列下排序的表上.作为外键的一部分并且使用外键的表.有人最好有一些聪明的递归CTE或存储过程来进行必要的排序吗?连接到数据库的程序不被视为解决方案.

编辑:我根据第一个解决方案在"答案"中发布了答案 任何转发我自己的"正确"答案的人都可以免费获得"正确答案"!

WITH 
 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, 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
ORDER BY Sorting

推荐答案

感谢您提供的工作解决方案NXC.您让我走上了使用递归CTE解决问题的正确道路.

WITH 
  TablesCTE(TableName, TableID, Ordinal) AS
  (
  SELECT 
    OBJECT_SCHEMA_NAME(so.id) +'.'+ OBJECT_NAME(so.id) AS TableName,
    so.id AS TableID,
    0 AS Ordinal
  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
  UNION ALL
  SELECT 
    OBJECT_SCHEMA_NAME(so.id) +'.'+ OBJECT_NAME(so.id) AS TableName,
    so.id AS TableID,
    tt.Ordinal + 1 AS Ordinal
  FROM 
    dbo.sysobjects so 
    INNER JOIN sys.all_columns ac ON so.ID = ac.object_id
    INNER JOIN sys.foreign_keys f 
      ON (f.parent_object_id = so.id AND f.parent_object_id != f.referenced_object_id)
    INNER JOIN TablesCTE tt ON f.referenced_object_id = tt.TableID
  WHERE
    so.type = 'U'
  AND
    ac.is_rowguidcol = 1
)  
SELECT DISTINCT 
  t.Ordinal,
  t.TableName
  FROM TablesCTE t
  INNER JOIN 
    (
    SELECT 
      TableName as TableName,
      Max (Ordinal) as Ordinal
    FROM TablesCTE
    GROUP BY TableName
    ) tt ON (t.TableName = tt.TableName  AND t.Ordinal = tt.Ordinal)
ORDER BY t.Ordinal, t.TableName

THooSE想知道这有什么用:我将使用它安全地清空数据库,而不会违反任何外键关系.(按降序截断) 通过以升序填充表,我还可以安全地用来自另一个数据库的数据填充表.

Database相关问答推荐

我们可以出于不同目的在同一 postgres 数据库上同时进行物理和逻辑复制吗?

从 GCP 机密管理器中读取 .DER 值并将其保存到 .DER 文件

创建一个spell check,判断具有合理运行时间的数据库

502 是数据库错误的适当状态代码吗?

将 .frm 和 .opt 文件导入 MySQL

MS Access:如何在 VBA 中压缩当前数据库

如何将 MySQL Workbench 连接到 Amazon RDS?

如何在 MSSQL 2005 中创建递归查询?

不同的数据库是否使用不同的名称引用?

如何决定使用什么 [Sqlite、Realm、CoreData、User-default、JSON 文件] 来存储 iOS 数据?

Tornado 的非阻塞 ORM?

在默认路径下使用脚本创建数据库?

如何在远程服务器上备份 MySQL 数据库?

如果数据库已经提供缓存,为什么还要使用应用程序级缓存?

从 postgresql 转储文件填充 MySQL 数据库

将 .csv 文件导入 Android 中的 Sqlite

Oracle:如何在 Oracle SQL 中将十六进制转换为十进制?

关系未更新的 NSFetchedResultsController

最佳事件采购数据库策略

获取 xp_cmdshell 的执行权限