I need a T-SQL query to fetch all relations in a SQL Server database and understand that each relation is of multiple order like one-to-one, one-to-many and many-to-many relation.
I can fetch all relation's but can't know each relation is one-to-one, one-to-many.
My query is this :
SELECT
FK.[name] AS ForeignKeyConstraintName
,SCHEMA_NAME(FT.schema_id) + '.' + FT.[name] AS ForeignTable
,STUFF(ForeignColumns.ForeignColumns, 1, 2, '') AS ForeignColumns
,SCHEMA_NAME(RT.schema_id) + '.' + RT.[name] AS ReferencedTable
,STUFF(ReferencedColumns.ReferencedColumns, 1, 2, '') AS ReferencedColumns,
'one-to-one or one-to-many or many-to-many' as RelationType
FROM
sys.foreign_keys FK
INNER JOIN
sys.tables FT ON FT.object_id = FK.parent_object_id
INNER JOIN
sys.tables RT ON RT.object_id = FK.referenced_object_id
CROSS APPLY
(SELECT
', ' + iFC.[name] AS [text()]
FROM
sys.foreign_key_columns iFKC
INNER JOIN
sys.columns iFC ON iFC.object_id = iFKC.parent_object_id
AND iFC.column_id = iFKC.parent_column_id
WHERE
iFKC.constraint_object_id = FK.object_id
ORDER BY
iFC.[name]
FOR XML PATH('')) ForeignColumns (ForeignColumns)
CROSS APPLY
(SELECT
', ' + iRC.[name] AS [text()]
FROM
sys.foreign_key_columns iFKC
INNER JOIN
sys.columns iRC ON iRC.object_id = iFKC.referenced_object_id
AND iRC.column_id = iFKC.referenced_column_id
WHERE
iFKC.constraint_object_id = FK.object_id
ORDER BY
iRC.[name]
FOR XML PATH('')) ReferencedColumns (ReferencedColumns)
What I can do ?
2条答案
按热度按时间wpcxdonn1#
It's not really possible to show Many-to-Many relationship by showing each foreign key on each table separately, because a Many-to-Many requires two separate relationships from a single table.
You can check if a relationship is One-to-One or Many-to-One, by checking if there is a unique index on the foreign table which matches the exact columns of the foreign key (no more, no less).
The easiest way to do this is probably to just aggregate the foreign keys into a JSON array then break it bac out using
OPENJSON
.db<>fiddle
The logic of the
OUTER APPLY
is basically a Relational Division:take all unique indexes of the foreign table
left-join the JSON array to it
then group up by
index_id
check that the number of index columns is both:
the same as the length of the array (no missing columns)
and the same as the number of matches between columns (no extra columns)
2izufjch2#
The solution is use "INFORMATION_SCHEMA" with a query i fetch all constraints and in result REFERENCED_TABLE_NAME is one side and FK_TABLE_NAME is many side of relation
Query Is :