列出具有复合键的SQL表关系

列出具有复合键的SQL表关系,sql,sql-server,foreign-keys,Sql,Sql Server,Foreign Keys,在组合键/外部字段正确排列在一起的情况下,列出表关系的SQL是什么?我的意思是: 我使用下面的SQL获取表关系: SELECT c.CONSTRAINT_NAME, cu.TABLE_SCHEMA AS ReferencingSchema, cu.TABLE_NAME AS ReferencingTable, cu.COLUMN_NAME AS ReferencingColumn, ku.TABLE_SCHEMA AS ReferencedSchema,

在组合键/外部字段正确排列在一起的情况下,列出表关系的SQL是什么?我的意思是:

我使用下面的SQL获取表关系:

SELECT
    c.CONSTRAINT_NAME,
    cu.TABLE_SCHEMA AS ReferencingSchema,
    cu.TABLE_NAME AS ReferencingTable,
    cu.COLUMN_NAME AS ReferencingColumn,
    ku.TABLE_SCHEMA AS ReferencedSchema,
    ku.TABLE_NAME AS ReferencedTable,
    ku.COLUMN_NAME AS ReferencedColumn
FROM
    INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS c
    INNER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE cu ON
        cu.CONSTRAINT_NAME = c.CONSTRAINT_NAME
    INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE ku ON
        ku.CONSTRAINT_NAME = c.UNIQUE_CONSTRAINT_NAME
这对于单列主键非常有效,但是当涉及到组合键时,事情就会分崩离析。e、 g.对于下面的FK,有2列参与了关系,但返回了4个未对齐的结果(因为笛卡尔积):

我希望结果是:

+-------------------------+------------------+-------------------+-------------------+------------------+
|CONSTRAINT_NAME          |ReferencingTable  | ReferencingColumn | ReferencedTable   | ReferencedColumn |
+-------------------------+------------------+-------------------+-------------------+------------------+
|FK_ACCOUNT_CHAINID_CHAIN | ACCOUNT          | CHAINID           | CHAIN             | CHAINID          |
|FK_ACCOUNT_CHAINID_CHAIN | ACCOUNT          | NTENTID           | CHAIN             | NTENTID          |
+-------------------------+------------------+-------------------+-------------------+------------------+
现在,我可以在引用中使用一个类似于自然的连接,通过向连接中添加
和cu.COLUMN_NAME=ku.COLUMN_NAME
来排列字段,但只有在名称相同且在许多情况下不相同的情况下,这才起作用(我不这么做)


我在
INFORMATION\u SCHEMA.KEY\u COLUMN\u USAGE
中查看了,它有
Ordinal\u Position
字段用于排序主键,但我在
INFORMATION\u SCHEMA.CONSTRAINT\u COLUMN\u USAGE
中没有看到类似的列,我不确定还能在哪里查看

那么,如果/在哪里/如何在复合表关系中排列引用列和被引用列呢



适用于SQL Server 2008 R2及更高版本。

以下内容应能满足您的需要,但我使用的是
sys
schema视图,而不是
INFORMATION\u schema

select
    quotename(fk.name) CONSTRAINT_NAME,
    quotename(s.name) + '.' + (t.name) ReferencingTable,
    quotename(c.name) ReferencingColumn,
    quotename(s2.name) + '.' + quotename(t2.name) ReferencedTable,
    quotename(c2.name) ReferencedColumn
from sys.foreign_keys fk
    join sys.foreign_key_columns fkc on fkc.constraint_object_id = fk.object_id
    join sys.tables t on t.object_id = fk.parent_object_id
    join sys.schemas s on s.schema_id = t.schema_id
    join sys.tables t2 on t2.object_id = fk.referenced_object_id
    join sys.schemas s2 on s2.schema_id = t2.schema_id
    join sys.columns c on c.column_id = fkc.parent_column_id and c.object_id = fk.parent_object_id
    join sys.columns c2 on c2.column_id = fkc.referenced_column_id and c2.object_id = fk.referenced_object_id
order by fk.name, fkc.constraint_column_id;
以上内容将返回所有FK的信息

您可以通过添加where子句来筛选组合:

select ...
from ...
where
    (select count(1) from sys.foreign_key_columns where constraint_object_id = fk.object_id) > 1
order by fk.name, fkc.constraint_column_id;

如果我理解正确,您希望只显示不同的值?在这种情况下,我们的选择是不同的statement@Backtrack不完全是。引用列和引用列是不同的,因此不同的列不起作用。在本例中,我试图将
ReferencedColumn
中的
CHAINID
ReferencedColumn
中的
CHAINID
ReferencedColumn
中的
NTENDID
绑定。但是如果在列名上有任何不同,如果我依赖他们的名字,他们就不会联系起来。这太棒了。谢谢我不认为使用
INFORMATION\u SCHEMA
select ...
from ...
where
    (select count(1) from sys.foreign_key_columns where constraint_object_id = fk.object_id) > 1
order by fk.name, fkc.constraint_column_id;