列出与复合键

时间:2016-02-08 12:27:27

标签: 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,
    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

哪个适用于单列主键,但是当涉及复合键时,事情就会崩溃。例如对于下面的FK,有两列参与这种关系,但返回了4个未对齐的结果(因为笛卡尔产品):

+-------------------------+------------------+-------------------+-------------------+------------------+
|CONSTRAINT_NAME          |ReferencingTable  | ReferencingColumn | ReferencedTable   | ReferencedColumn |
+-------------------------+------------------+-------------------+-------------------+------------------+
|FK_ACCOUNT_CHAINID_CHAIN | ACCOUNT          | CHAINID           | CHAIN             | CHAINID          |
|FK_ACCOUNT_CHAINID_CHAIN | ACCOUNT          | CHAINID           | CHAIN             | NTENTID          |
|FK_ACCOUNT_CHAINID_CHAIN | ACCOUNT          | NTENTID           | CHAIN             | CHAINID          |
|FK_ACCOUNT_CHAINID_CHAIN | ACCOUNT          | NTENTID           | CHAIN             | NTENTID          |
+-------------------------+------------------+-------------------+-------------------+------------------+

我希望结果是:

+-------------------------+------------------+-------------------+-------------------+------------------+
|CONSTRAINT_NAME          |ReferencingTable  | ReferencingColumn | ReferencedTable   | ReferencedColumn |
+-------------------------+------------------+-------------------+-------------------+------------------+
|FK_ACCOUNT_CHAINID_CHAIN | ACCOUNT          | CHAINID           | CHAIN             | CHAINID          |
|FK_ACCOUNT_CHAINID_CHAIN | ACCOUNT          | NTENTID           | CHAIN             | NTENTID          |
+-------------------------+------------------+-------------------+-------------------+------------------+

现在,我可以在Referencing-和Referenced-columns上使用类似自然的连接来排列字段 - 通过向连接添加AND cu.COLUMN_NAME = ku.COLUMN_NAME,但这只有在名称相同且很多时才有效他们不是(不是我的)。

我查看了INFORMATION_SCHEMA.KEY_COLUMN_USAGE,其中有Ordinal_Position字段用于订购主键,但我还没有看到INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE中的类似列,而且我还没有不确定在哪里看。

那么if / where /我如何排列复合表关系中的引用和引用列?

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

1 个答案:

答案 0 :(得分:1)

以下内容应该为您提供所需内容,但我使用的是sys架构视图,而不是INFORMATION_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;