查询以查找所有 FK 约束及其引用的 table 列
Query to find all FK constraints, and their referenced table columns
我有一个大型 SQL 2012 数据库(100 tables),我需要在其中找到引用操作设置为 CASCADE(更新或删除)的所有约束。
在 this useful answer 中,我看到我可以使用以下 T-SQL(稍作修改)列出约束:
SELECT
name,
delete_referential_action_desc,
update_referential_action_desc
FROM
sys.foreign_keys
WHERE
update_referential_action_desc = 'CASCADE' OR
delete_referential_action_desc = 'CASCADE';
这提供了一个有用的列表:
name delete_referential_action_desc update_referential_action_desc
----------------------------------------------------------------------
FK_name001 CASCADE CASCADE
FK_name002 CASCADE NO_ACTION
FK_name003 CASCADE NO_ACTION
但是,是否可以扩展代码,以便为每个约束包含各自的 table 名称和列名称,例如?
name delete_referential_action_desc update_referential_action_desc ParentTable ParentCol ChildTable ChildCol
----------------------------------------------------------------------------------------------------------------------------
FK_name001 CASCADE CASCADE Table1 Col1 Table2 Col2
我尝试了不同的编辑,从 sys.objects
中提取值,但无法弄清楚它是如何工作的,或者这是否是正确的方法。
更新
请注意,我不想到ALTER
任何东西,或进行任何架构更改。我只想查看一个列表,以便我可以手动执行进一步的操作。我没有信心也没有经验edit this gigantic query把重点拉出来
经过两天的实验,我已经非常接近我需要的东西终于解决了它,使用this answer作为基础:
SELECT
C.CONSTRAINT_NAME,
PK.TABLE_NAME,
CCU.COLUMN_NAME,
FK.TABLE_NAME,
CU.COLUMN_NAME,
C.UPDATE_RULE,
C.DELETE_RULE
FROM
INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS C INNER JOIN
INFORMATION_SCHEMA.TABLE_CONSTRAINTS FK ON C.CONSTRAINT_NAME = FK.CONSTRAINT_NAME INNER JOIN
INFORMATION_SCHEMA.TABLE_CONSTRAINTS PK ON C.UNIQUE_CONSTRAINT_NAME = PK.CONSTRAINT_NAME INNER JOIN
INFORMATION_SCHEMA.KEY_COLUMN_USAGE CU ON C.CONSTRAINT_NAME = CU.CONSTRAINT_NAME INNER JOIN
INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE CCU ON PK.CONSTRAINT_NAME = CCU.CONSTRAINT_NAME
WHERE
((C.UPDATE_RULE = 'CASCADE') OR (C.DELETE_RULE = 'CASCADE')) AND
(FK.CONSTRAINT_TYPE = 'FOREIGN KEY')
ORDER BY
PK.TABLE_NAME,
FK.TABLE_NAME;
赞美数字之神...(!)
我有一个大型 SQL 2012 数据库(100 tables),我需要在其中找到引用操作设置为 CASCADE(更新或删除)的所有约束。
在 this useful answer 中,我看到我可以使用以下 T-SQL(稍作修改)列出约束:
SELECT
name,
delete_referential_action_desc,
update_referential_action_desc
FROM
sys.foreign_keys
WHERE
update_referential_action_desc = 'CASCADE' OR
delete_referential_action_desc = 'CASCADE';
这提供了一个有用的列表:
name delete_referential_action_desc update_referential_action_desc
----------------------------------------------------------------------
FK_name001 CASCADE CASCADE
FK_name002 CASCADE NO_ACTION
FK_name003 CASCADE NO_ACTION
但是,是否可以扩展代码,以便为每个约束包含各自的 table 名称和列名称,例如?
name delete_referential_action_desc update_referential_action_desc ParentTable ParentCol ChildTable ChildCol
----------------------------------------------------------------------------------------------------------------------------
FK_name001 CASCADE CASCADE Table1 Col1 Table2 Col2
我尝试了不同的编辑,从 sys.objects
中提取值,但无法弄清楚它是如何工作的,或者这是否是正确的方法。
更新
请注意,我不想到ALTER
任何东西,或进行任何架构更改。我只想查看一个列表,以便我可以手动执行进一步的操作。我没有信心也没有经验edit this gigantic query把重点拉出来
经过两天的实验,我已经非常接近我需要的东西终于解决了它,使用this answer作为基础:
SELECT
C.CONSTRAINT_NAME,
PK.TABLE_NAME,
CCU.COLUMN_NAME,
FK.TABLE_NAME,
CU.COLUMN_NAME,
C.UPDATE_RULE,
C.DELETE_RULE
FROM
INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS C INNER JOIN
INFORMATION_SCHEMA.TABLE_CONSTRAINTS FK ON C.CONSTRAINT_NAME = FK.CONSTRAINT_NAME INNER JOIN
INFORMATION_SCHEMA.TABLE_CONSTRAINTS PK ON C.UNIQUE_CONSTRAINT_NAME = PK.CONSTRAINT_NAME INNER JOIN
INFORMATION_SCHEMA.KEY_COLUMN_USAGE CU ON C.CONSTRAINT_NAME = CU.CONSTRAINT_NAME INNER JOIN
INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE CCU ON PK.CONSTRAINT_NAME = CCU.CONSTRAINT_NAME
WHERE
((C.UPDATE_RULE = 'CASCADE') OR (C.DELETE_RULE = 'CASCADE')) AND
(FK.CONSTRAINT_TYPE = 'FOREIGN KEY')
ORDER BY
PK.TABLE_NAME,
FK.TABLE_NAME;
赞美数字之神...(!)