3

我正在尝试使用以下递归 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 资源。Microsoft 的尽职调查可以防止这种情况发生。我想知道我是否可以在没有while循环的情况下使用单个查询并且没有临时表来做到这一点。

我知道我的根表名称和我的根列 id,我也知道我的叶节点表名称,虽然我不能说什么可能是叶节点列名称

我必须找到这个,因为我正在运行时设计一个查询并执行它。此查询需要在运行时构造 ON 子句之间的内部连接。不确定我是否有意义。

4

1 回答 1

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
于 2012-11-19T21:28:37.623 回答