如何通过查询获取SQL表外键类型

时间:2019-01-10 19:40:25

标签: sql sql-server

我必须在Web应用程序上显示数据库图。当用户选择数据库表时,我需要将关系表和关系类型显示为“一对一”,“一对多”或“多对多”。

到目前为止,我能够使用下面的查询获得除关系类型以外的所有我需要的细节。

但是我找不到获取关系类型的方法。你能帮我吗?

SELECT 
    t.name AS Parent_TableName,
    COL_NAME(fc.referenced_object_id, fc.referenced_column_id) Parent_Id,
    f.Name AS foreign_key_Name,
    OBJECT_NAME(f.parent_object_id) ReferenceTableName,
    COL_NAME(fc.parent_object_id, fc.parent_column_id) ColName
FROM 
    sys.foreign_keys AS f 
INNER JOIN 
    sys.foreign_key_columns AS fc ON f.OBJECT_ID = fc.constraint_object_id
INNER JOIN 
    sys.tables t ON t.OBJECT_ID = fc.referenced_object_id
WHERE 
    OBJECT_NAME (f.referenced_object_id) ='Category'

enter image description here

2 个答案:

答案 0 :(得分:3)

查看列上的唯一约束类型可能有用吗?在下面,我添加了一个检查以查看父表键和子表键的约束类型是否唯一。如果它们都是唯一的,那就是一对一的关系。如果一个是唯一的,那么它就是一对多的;如果都不是唯一的,那么它是一对多的...我只是在说明“一对一”的检查。如果没有,我默认为“其他”

已更新:我添加了“一对多”检查。我还添加了对“主键”和“唯一”约束的检查。

With tbl As
(
SELECT 
   t.name as Parent_TableName,
   COL_NAME(fc.referenced_object_id,fc.referenced_column_id) Parent_Id,
   f.Name as foreign_key_Name,
   OBJECT_NAME(f.parent_object_id) ReferranceTableName,
   COL_NAME(fc.parent_object_id,fc.parent_column_id) ColName
FROM sys.foreign_keys AS f 
     INNER JOIN sys.foreign_key_columns AS fc ON f.OBJECT_ID = fc.constraint_object_id
     INNER JOIN sys.tables t ON t.OBJECT_ID = fc.referenced_object_id
  WHERE OBJECT_NAME (f.referenced_object_id) ='Category'
)
Select 
   *,Case When 
        (

        Exists 
        (
        SELECT * 
        FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc 
             inner join INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE cu 
             on cu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME 
        Where 
             (tc.CONSTRAINT_TYPE = 'Primary Key' Or tc.CONSTRAINT_TYPE = 'Unique') and 
             tc.TABLE_NAME = tbl.Parent_TableName and
             cu.COLUMN_NAME = tbl.Parent_Id
        ) 

        And

        Exists 
        (
        SELECT * 
        FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc 
             inner join INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE cu 
             on cu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME 
        Where 
            (tc.CONSTRAINT_TYPE = 'Primary Key' Or tc.CONSTRAINT_TYPE = 'Unique') and 
             tc.TABLE_NAME = tbl.ReferranceTableName and
             cu.COLUMN_NAME = tbl.ColName
        ) 

       ) Then 'One to One' 

/***********Check if the Parent or Child is Unique**Suggestiong a One to Many Relationship********/    
When 
        (  

       Not Exists 
        (
        SELECT * 
        FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc 
             inner join INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE cu 
             on cu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME 
        Where 
             (tc.CONSTRAINT_TYPE = 'Primary Key' Or tc.CONSTRAINT_TYPE = 'Unique') and 
             tc.TABLE_NAME = tbl.Parent_TableName and
             cu.COLUMN_NAME = tbl.Parent_Id
        ) 

        And

        Exists 
        (
        SELECT * 
        FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc 
             inner join INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE cu 
             on cu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME 
        Where 
             (tc.CONSTRAINT_TYPE = 'Primary Key' Or tc.CONSTRAINT_TYPE = 'Unique') and 
             tc.TABLE_NAME = tbl.ReferranceTableName and
             cu.COLUMN_NAME = tbl.ColName
        ) 

       ) 

       Or  -- Check if the child is unique and the Parent is not
        (

        Exists 
        (
        SELECT * 
        FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc 
             inner join INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE cu 
             on cu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME 
        Where 
             (tc.CONSTRAINT_TYPE = 'Primary Key' Or tc.CONSTRAINT_TYPE = 'Unique') and 
             tc.TABLE_NAME = tbl.Parent_TableName and
             cu.COLUMN_NAME = tbl.Parent_Id
        ) 

        And

       Not  Exists 
        (
        SELECT * 
        FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc 
             inner join INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE cu 
             on cu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME 
        Where 
             (tc.CONSTRAINT_TYPE = 'Primary Key' Or tc.CONSTRAINT_TYPE = 'Unique') and 
             tc.TABLE_NAME = tbl.ReferranceTableName and
             cu.COLUMN_NAME = tbl.ColName
        ) 

       )       

       Then 'One to Many' 

/******************************************************************/       

         Else 'Other' 
       End As [Relationship] 
From tbl

答案 1 :(得分:1)

要在关系检查中检查条件的结果,请查找表的约束以查看哪些表具有“唯一”和/或“主键”

要查找表上的约束,请执行以下操作:

SELECT * 
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc 
     inner join INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE cu 
     on cu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME 
where 
     tc.TABLE_NAME = 'TABLENAME' and
     cu.COLUMN_NAME = 'COLUMNNAME'

要查找表中外键的数量以查找多个推断可能存在“多对多”关系的外键:

        SELECT Count(*) 
        FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc 
             inner join INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE cu 
             on cu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME 
        Where 
             tc.TABLE_NAME = 'TABLENAME' and
             tc.CONSTRAINT_TYPE = 'FOREIGN KEY'