我有一个庞大的数据库,有很多很少记录的约束。 我需要编写一些SQL来清除这些表的子集中的数据,我不知道如何确定删除的顺序。显然我需要在相应的PK表之前删除FK表,但正如我所说,这些关系是纠结的,并且记录不完整。
是否有可用的工具可以让我确定删除语句的正确顺序?
(我查看了Red Gate工具,并且非常惊讶地发现它们不支持我正在使用的SQL Server 2008R2。)
答案 0 :(得分:0)
我认为您可以构建一个程序来获取订单。这是一个想法:
CREATE PROCEDURE get_delete_order
@tablename varchar(MAX)
as
BEGIN
-- Get directed related tables
SELECT base.name base_name
, related.name rel_name
into #RELATED_TABLES
FROM sys.sysobjects base
left join sys.sysforeignkeys on fkeyid = base.id
left join sys.sysobjects related on related.id = rkeyid
and related.id <> base.id
and related.xtype = 'U'
WHERE base.xtype = 'U'
and base.name = @tablename
-- Get indirected related tables using recursive call
CREATE #ALL_RELATED_TABLES (rel_name varchar(max), del_order int)
INSERT INTO #ALL_RELATED_TABLES (rel_name, del_order)
SELECT rel_name
, -1
FROM #RELATED_TABLES
DECLARE @relate_table
DECLARE IND_REL CURSOR FOR
SELECT rel_Name
FROM #RELATED_TABLES
open IND_REL
fetch next from IND_REL into @relate_table
-- TODO: IMPORTANT!!! Avoid infinite loop here
while (@@FETCH_STATUS = 0)
begin
INSERT INTO #ALL_RELATED_TABLES (rel_name, del_order)
exec get_delete_order(@relate_table)
fetch next from IND_REL into @relate_table
end
close IND_REL
deallocate IND_REL
-- Return resultset
SELECT rel_name
, del_order + 1
FROM #ALL_RELATED_TABLES
ORDER BY del_order DESC
END
这是未经考验的,只是一个想法。 真正的程序会更复杂:)
答案 1 :(得分:0)
只需在此处粘贴Fred Fred博客中的脚本以备将来参考。对我来说效果很好。
select cast(f.name as varchar(255)) as foreign_key_name
, r.keycnt
, cast(c.name as varchar(255)) as foreign_table
, cast(fc.name as varchar(255)) as foreign_column_1
, cast(fc2.name as varchar(255)) as foreign_column_2
, cast(p.name as varchar(255)) as primary_table
, cast(rc.name as varchar(255)) as primary_column_1
, cast(rc2.name as varchar(255)) as primary_column_2
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))