我写了一个查询来找出数据库中所有表之间的主键-外键关系。这只有在我们物理上存在外键时才有效。
请运行此查询以清楚地了解我的问题。
WITH cte
AS
(
SELECT
fk.create_date
, fk.modify_date
, fkc.constraint_object_id AS ConstraintId
, OBJECT_NAME(fkc.constraint_object_id) AS ConstraintName
--, fkc.referenced_object_id AS PrimaryKeyTableId
, OBJECT_NAME(fkc.referenced_object_id) AS PrimaryKeyTableName
--, fkc.referenced_column_id AS PrimaryKeyColumnId
, rc.name AS PrimaryKeyColumnName
--, fk.parent_object_id AS ForeignKeyTableId
, OBJECT_NAME(fk.parent_object_id) AS ForeignKeyTableName
--, fkc.parent_column_id AS ForeignKeyColumnId
, lc.name AS ForeignKeyColumnName
FROM sys.foreign_key_columns fkc
INNER JOIN sys.columns rc
ON rc.OBJECT_ID = fkc.referenced_object_id
AND fkc.referenced_column_id = rc.column_id
INNER JOIN sys.foreign_keys fk
ON fk.OBJECT_ID = fkc.constraint_object_id
INNER JOIN sys.columns lc
ON lc.OBJECT_ID = fk.parent_object_id
AND fkc.parent_column_id = lc.column_id
)
, cte2(create_date, modify_date, ConstraintName
, PrimaryKeyTableName, PrimaryKeyColumnName
, ForeignKeyTableName, ForeignKeyColumnName
, Hops, path ) AS
(
SELECT
create_date, modify_date, ConstraintName
, PrimaryKeyTableName, PrimaryKeyColumnName
, ForeignKeyTableName, ForeignKeyColumnName
, 1 , CAST(QUOTENAME(PrimaryKeyTableName + '.' + PrimaryKeyColumnName) AS VARCHAR(4000))
FROM cte
UNION ALL
SELECT
cte.create_date, cte.modify_date, cte.ConstraintName
, cte.PrimaryKeyTableName, cte.PrimaryKeyColumnName
, cte.ForeignKeyTableName, cte.ForeignKeyColumnName
, cte2.Hops +1, CAST(cte2.path + '-> ' +QUOTENAME(cte.PrimaryKeyTableName+ '.' + cte.PrimaryKeyColumnName) AS VARCHAR(4000))
FROM cte2 INNER JOIN cte ON cte2.ForeignKeyTableName = cte.PrimaryKeyTableName
AND cte2.ForeignKeyColumnName != cte.PrimaryKeyColumnName
)
SELECT
ConstraintName
, PrimaryKeyTableName, PrimaryKeyColumnName
, ForeignKeyTableName, ForeignKeyColumnName
, Hops, path + '-> ' + QUOTENAME(ForeignKeyTableName + '.' + ForeignKeyColumnName) AS Path
FROM cte2
除非我们在数据库中存在复合主键,否则上述查询工作顺利。
假设我有一张桌子
- 方法(方法 ID,....)
- 参数(ParameterId,...)
- ParameterMethodMap(ParameterId, MethodId) --复合主键
- Test(TestId, ParameterId, MethodId....) --复合主键被用作外键
- 样品(样品 ID,测试 ID ....)
因此,考虑到复合主键场景,当前查询不会生成路径。
我想生成类似的路径。
[Method.MethodId] -> [ParameterMethodMap.MethodId, ParameterMethodMap.ParameterId] -> [Test.TestId] -> [Sample.SampleId]
这就是我想合并复合主键的方式。我怎样才能做到这一点?