TSQL:获取受级联删除影响的所有表

发布于 2025-01-09 21:30:22 字数 100 浏览 5 评论 0原文

我正在寻找一个 SQL 脚本,该脚本将列出从表 X 中删除记录时将受到影响的所有表。 它还应该列出“树”下受影响的依赖表,因为受影响的表将对其他表进行级联删除,这反过来又会影响其他表等。

I'm looking for a SQL script that will list all tables that will be affected when deleting a record from table X.
It should also list the dependent tables affected down the "tree" as the affected tables will have cascade deletes to other, which in turn will affect others etc.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

迷荒 2025-01-16 21:30:22

您可以使用递归 CTE 生成受影响表的完整层次结构,例如,

WITH OnDelete AS
(   SELECT f.parent_object_id,
            f.referenced_object_id,
            RecursionLevel = 1,
            ObjectTree = CONVERT(VARCHAR(MAX), CONCAT(OBJECT_NAME(f.parent_object_id), ' --> ', OBJECT_NAME(f.referenced_object_id)))
    FROM sys.foreign_keys AS f
    WHERE f.delete_referential_action_desc = 'CASCADE'
    UNION ALL
    SELECT  od.parent_object_id,
            f.referenced_object_id,
            od.RecursionLevel + 1,
            ObjectTree = CONVERT(VARCHAR(MAX), CONCAT(od.ObjectTree, ' --> ', OBJECT_NAME(f.referenced_object_id)))
    FROM    OnDelete AS od
            INNER JOIN sys.foreign_keys AS f
                ON f.parent_object_id = od.referenced_object_id
                AND f.delete_referential_action_desc = 'CASCADE'

)
SELECT  BaseTable = OBJECT_NAME(od.parent_object_id),
        OnDelete = od.ObjectTree
FROM    OnDelete AS od
WHERE   NOT EXISTS
        (   SELECT  1
            FROM    OnDelete AS ex
            WHERE   ex.parent_object_id = od.parent_object_id
            AND     ex.ObjectTree LIKE CONCAT(od.ObjectTree, '%')
            AND     LEN(ex.ObjectTree) > LEN(od.ObjectTree)
        )
ORDER BY od.parent_object_id;

这将输出类似以下内容的内容:

BaseTableOnDelete
T2T2 --> T1
T3T3 --> T2——> T1
T4T4 --> T3——> T2——> T1
T5T5 --> T4——> T3——> T2——> T1

db<>fiddle 示例

You can use a recursive CTE to generate a full hierarchy of tables affected, e.g.

WITH OnDelete AS
(   SELECT f.parent_object_id,
            f.referenced_object_id,
            RecursionLevel = 1,
            ObjectTree = CONVERT(VARCHAR(MAX), CONCAT(OBJECT_NAME(f.parent_object_id), ' --> ', OBJECT_NAME(f.referenced_object_id)))
    FROM sys.foreign_keys AS f
    WHERE f.delete_referential_action_desc = 'CASCADE'
    UNION ALL
    SELECT  od.parent_object_id,
            f.referenced_object_id,
            od.RecursionLevel + 1,
            ObjectTree = CONVERT(VARCHAR(MAX), CONCAT(od.ObjectTree, ' --> ', OBJECT_NAME(f.referenced_object_id)))
    FROM    OnDelete AS od
            INNER JOIN sys.foreign_keys AS f
                ON f.parent_object_id = od.referenced_object_id
                AND f.delete_referential_action_desc = 'CASCADE'

)
SELECT  BaseTable = OBJECT_NAME(od.parent_object_id),
        OnDelete = od.ObjectTree
FROM    OnDelete AS od
WHERE   NOT EXISTS
        (   SELECT  1
            FROM    OnDelete AS ex
            WHERE   ex.parent_object_id = od.parent_object_id
            AND     ex.ObjectTree LIKE CONCAT(od.ObjectTree, '%')
            AND     LEN(ex.ObjectTree) > LEN(od.ObjectTree)
        )
ORDER BY od.parent_object_id;

This will output something like:

BaseTableOnDelete
T2T2 --> T1
T3T3 --> T2 --> T1
T4T4 --> T3 --> T2 --> T1
T5T5 --> T4 --> T3 --> T2 --> T1

Example on db<>fiddle

愿与i 2025-01-16 21:30:22
-- using sys tables to enumerate foreign keys
    SELECT
        f.name constraint_name
       ,OBJECT_NAME(f.parent_object_id) referencing_table_name
       ,COL_NAME(fc.parent_object_id, fc.parent_column_id) referencing_column_name
       ,OBJECT_NAME (f.referenced_object_id) referenced_table_name
       ,COL_NAME(fc.referenced_object_id, fc.referenced_column_id) referenced_column_name
       ,delete_referential_action_desc
       ,update_referential_action_desc
    FROM sys.foreign_keys AS f
    INNER JOIN sys.foreign_key_columns AS fc
       ON f.object_id = fc.constraint_object_id
    ORDER BY f.name
-- using sys tables to enumerate foreign keys
    SELECT
        f.name constraint_name
       ,OBJECT_NAME(f.parent_object_id) referencing_table_name
       ,COL_NAME(fc.parent_object_id, fc.parent_column_id) referencing_column_name
       ,OBJECT_NAME (f.referenced_object_id) referenced_table_name
       ,COL_NAME(fc.referenced_object_id, fc.referenced_column_id) referenced_column_name
       ,delete_referential_action_desc
       ,update_referential_action_desc
    FROM sys.foreign_keys AS f
    INNER JOIN sys.foreign_key_columns AS fc
       ON f.object_id = fc.constraint_object_id
    ORDER BY f.name
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文