我需要列出所有依赖于彼此的表
示例
TableA与TableB具有外键关系 TableB与TableA具有外键关系
到目前为止,我得到了脚本来查找表的外键关系,但是如何过滤它们以获得交叉表引用。
我的脚本是:
SELECT CAST(p.name AS VARCHAR(255)) AS [Primary Table] ,
CAST(c.name AS VARCHAR(255)) AS [Foreign Table]
FROM sysobjects f
INNER JOIN sysobjects c ON f.parent_obj = c.id
INNER JOIN sysreferences r ON f.id = r.constid
INNER JOIN sysobjects p ON r.rkeyid = p.id
INNER JOIN syscolumns rc ON r.rkeyid = rc.id
AND r.rkey1 = rc.colid
INNER JOIN syscolumns fc ON r.fkeyid = fc.id
AND r.fkey1 = fc.colid
LEFT JOIN syscolumns rc2 ON r.rkeyid = rc2.id
AND r.rkey2 = rc.colid
LEFT JOIN syscolumns fc2 ON r.fkeyid = fc2.id
AND r.fkey2 = fc.colid
WHERE f.type = 'F'
ORDER BY CAST(p.name AS VARCHAR(255))
答案 0 :(得分:0)
这个简单的select语句返回数据库中的循环直接外键引用:
IF OBJECT_ID('dbo.d') IS NOT NULL DROP TABLE dbo.d;
IF OBJECT_ID('dbo.c') IS NOT NULL DROP TABLE dbo.c;
IF OBJECT_ID('dbo.b') IS NOT NULL
BEGIN
ALTER TABLE dbo.a DROP CONSTRAINT [dbo.a(bid)->dbo.b(bid)];
DROP TABLE dbo.b;
END
IF OBJECT_ID('dbo.a') IS NOT NULL DROP TABLE dbo.a;
CREATE TABLE dbo.a(aid INT PRIMARY KEY CLUSTERED, bid INT);
CREATE TABLE dbo.b(aid INT CONSTRAINT [dbo.b(aid)->dbo.a(aid)] REFERENCES dbo.a(aid), bid INT PRIMARY KEY CLUSTERED);
ALTER TABLE dbo.a ADD CONSTRAINT [dbo.a(bid)->dbo.b(bid)] FOREIGN KEY(bid) REFERENCES dbo.b(bid);
CREATE TABLE dbo.c(cid INT PRIMARY KEY CLUSTERED);
CREATE TABLE dbo.d(did INT PRIMARY KEY CLUSTERED, cid INT CONSTRAINT [dbo.d(cid)->dbo.c(cid)] REFERENCES dbo.c(cid));
SELECT *
FROM sys.foreign_keys fk1
JOIN sys.foreign_keys fk2
ON fk1.parent_object_id = fk2.referenced_object_id
AND fk2.parent_object_id = fk1.referenced_object_id;
您可以在此处加入DMV sys.tables
和sys.columns
,以获取表名和列名等附加信息。
要注意两件事:
您应该停止使用兼容性视图。它们用于支持为SQL 2000编写的旧脚本,不应在新开发中使用。
外键中最多可包含16列。您的脚本仅支持两个。但是,如果不需要列名,则根本不返回列名,因此根本不应加入sys.columns。
如果您只需要表格的名称,则可以通过使用此选择语句而无需额外的连接而离开:
SELECT
QUOTENAME(OBJECT_SCHEMA_NAME(fk1.parent_object_id))+'.'+QUOTENAME(OBJECT_NAME(fk1.parent_object_id))+
' <-> '+
QUOTENAME(OBJECT_SCHEMA_NAME(fk1.referenced_object_id))+'.'+QUOTENAME(OBJECT_NAME(fk1.referenced_object_id))
FROM sys.foreign_keys fk1
JOIN sys.foreign_keys fk2
ON fk1.parent_object_id = fk2.referenced_object_id
AND fk2.parent_object_id = fk1.referenced_object_id
AND fk1.parent_object_id < fk1.referenced_object_id;
我还在查询的WHERE子句中添加了一个附加条件,只包含一对。