2012-11-01 66 views
1

如何构造一个查询以获取外键关联依赖关系的SQL Server表名?通过外键关联获取表名的SQL查询

如果有一个表XYZ,它是其他两个表有外键约束的主表,那么我希望表XYZ首先出现。

这是为了以正确的顺序创建表。

+2

它更容易建立一个没有外键的表,然后改变它们之后,你不明白这个问题。另外,一般的问题是不可解决的,因为你可以有循环依赖(虽然这通常是不好的设计) – Laurence

+0

作为一个侧面提示,在VS2010中使用SQL Server Projects会自动为你做。 –

回答

-2

您可以在下面的表格你想要的信息:

select * from sys.tables 
select * from sys.foreign_keys 
select * from sys.foreign_key_columns 

从那里,建立脚本你需要将这样做。

0

这个查询将在他们的依赖顺序返回表:

 ;WITH vwTableDependancy AS (
     SELECT 
      tables.object_id Dependant , NULL Parent 
     FROM 
      sys.tables 
     LEFT OUTER JOIN 
      sys.foreign_keys 
     ON 
      foreign_keys.parent_object_id = tables.object_id 
     WHERE 
      foreign_keys.parent_object_id IS NULL 
     UNION  
     SELECT 
      parent_object_id Dependant, referenced_object_id Parent 
     FROM 
      sys.foreign_keys 
    ) 
    , vwTableHierarchy AS (
     SELECT Dependant,Parent, 0 lvl FROM vwTableDependancy WHERE Parent IS NULL 
     UNION ALL 
     SELECT 
      vwTableDependancy.Dependant,vwTableDependancy.Parent , lvl+1 
     FROM 
      vwTableDependancy 
     INNER JOIN 
      vwTableHierarchy 
     ON 
      vwTableDependancy.Parent = vwTableHierarchy.Dependant 
    ) 
    SELECT 
     OBJECT_NAME(Dependant) Dependant 
     ,OBJECT_NAME(Parent) Parent 
     , lvl 
    FROM 
     vwTableHierarchy 
    ORDER BY 
     lvl ASC 
    OPTION(MAXRECURSION 0) 
+0

我知道这已经有点老了,但正如@劳力士指出的那样,循环依赖会打破这一点。 'MAXRECUSRION'设置为'0',如果你有一个循环依赖,那么这个查询将运行,直到你得到一个系统内存异常。您可以向CTE添加一个排除,以拒绝任何可以工作的记录(parent_object_id = referenced_object_id)(在[此SQL小提琴](http://sqlfiddle.com/#!3/0d029/1)中演示)。 –

0
select * from sys.tables st 
join sys.foreign_keys sfk on st.object_id = sfk.parent_object_id 
where sfk.name = 'Foreign_Key'