我试图使用以下递归CTE查询从下到上找到表的引用表
With CTE_ALL AS
(
SELECT
1 as TopLevel, c.CONSTRAINT_NAME, cu.TABLE_NAME AS ReferencingTable,
cu.COLUMN_NAME AS ReferencingColumn,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
where cu.TABLE_NAME = 'my table name'
Union All
SELECT
2 as BelowLevels, c.CONSTRAINT_NAME, cu.TABLE_NAME AS ReferencingTable,
cu.COLUMN_NAME AS ReferencingColumn,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
INNER JOIN CTE_ALL CTE on CTE.ReferencedColumn = ku.COLUMN_NAME
and CTE.ReferencedTable = ku.TABLE_NAME
)
select *
from CTE_ALL
where CTE_ALL.ReferencingTable = 'my table name'
错误地显示以下消息
Msg 530, Level 16, State 1, Line 1
The statement terminated. The maximum recursion 100 has been exhausted before
statement completion.
这显然意味着我的查询被狡猾地计划耗尽所有SQL资源。 微软的尽职调查阻止了这一点。 我想知道如果没有使用单个查询的while循环而没有临时表,我是否可以这样做。
我知道我的根表名和我的根列id,我也知道我的叶节点表名,虽然我不能说叶子节点列名可能是什么
我必须找到这个,因为我在运行时设计一个查询并执行它。此查询需要在运行时构造的ON子句之间的内部联接。不确定我是否理解我想要的。
答案 0 :(得分:2)
经过几天的尝试和研究,我找到了一种方法来帮助自己,并且在了解递归CTE之后也更好。
对于所有可能认为有用的人
这是我可以最终确定的查询
DECLARE @REFERENCED_COLUMN VARCHAR(50) = 'MyColumn'
DECLARE @REFERENCING_TABLE VARCHAR(50) = 'MyTable'
;WITH
CTE_Relationship (ReferencingTable, ReferencingColumn, ReferencedTable, ReferencedColumn) AS
(
SELECT
CU.TABLE_NAME AS ReferencingTable, CU.COLUMN_NAME AS ReferencingColumn,
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
),
CTE_Recursive_Relationship (ReferencingTable, ReferencingColumn, ReferencedTable, ReferencedColumn, Pass) AS
(
SELECT
R.ReferencingTable, R.ReferencingColumn, R.ReferencedTable, R.ReferencedColumn, 1 AS Pass
FROM
CTE_Relationship R
WHERE
R.ReferencingTable = @REFERENCING_TABLE
UNION ALL
SELECT
R.ReferencingTable, R.ReferencingColumn, R.ReferencedTable, R.ReferencedColumn, RR.Pass + 1
FROM
CTE_Relationship R
INNER JOIN CTE_Recursive_Relationship RR ON R.ReferencingTable = RR.ReferencedTable
AND R.ReferencedColumn = @REFERENCED_COLUMN
)
SELECT
DISTINCT RR.*
FROM
CTE_Recursive_Relationship RR
ORDER BY RR.Pass