在SSMS 2016中如何批量删除并恢复引用表的外键约束?
嘿,这个需求我太熟悉了——要批量删外键、操作表再恢复,其实核心就是先把外键的“备份”做好,再按步骤来就行。给你一套稳扎稳打的流程:
第一步:生成外键的删除与恢复脚本
首先得把所有引用mytable1的外键约束的删除语句和重建语句都生成出来,这一步是关键,避免手动写脚本出错。你可以在SSMS里执行下面的SQL(记得把mytable1换成带 schema 的完整表名,比如dbo.mytable1):
-- 生成删除外键的脚本 + 重建外键的脚本 SELECT -- 删除外键的语句 'ALTER TABLE ' + QUOTENAME(OBJECT_SCHEMA_NAME(fk.parent_object_id)) + '.' + QUOTENAME(OBJECT_NAME(fk.parent_object_id)) + ' DROP CONSTRAINT ' + QUOTENAME(fk.name) + ';' AS DropFKScript, -- 重建外键的语句 'ALTER TABLE ' + QUOTENAME(OBJECT_SCHEMA_NAME(fk.parent_object_id)) + '.' + QUOTENAME(OBJECT_NAME(fk.parent_object_id)) + ' ADD CONSTRAINT ' + QUOTENAME(fk.name) + ' FOREIGN KEY (' + STUFF((SELECT ', ' + QUOTENAME(c.name) FROM sys.foreign_key_columns fkc JOIN sys.columns c ON fkc.parent_object_id = c.object_id AND fkc.parent_column_id = c.column_id WHERE fkc.constraint_object_id = fk.object_id ORDER BY fkc.constraint_column_id FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, '') + ') REFERENCES ' + QUOTENAME(OBJECT_SCHEMA_NAME(fk.referenced_object_id)) + '.' + QUOTENAME(OBJECT_NAME(fk.referenced_object_id)) + ' (' + STUFF((SELECT ', ' + QUOTENAME(c.name) FROM sys.foreign_key_columns fkc JOIN sys.columns c ON fkc.referenced_object_id = c.object_id AND fkc.referenced_column_id = c.column_id WHERE fkc.constraint_object_id = fk.object_id ORDER BY fkc.constraint_column_id FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, '') + ');' AS CreateFKScript FROM sys.foreign_keys fk WHERE fk.referenced_object_id = OBJECT_ID('mytable1');
执行完后,把结果里的DropFKScript列所有语句复制出来,保存成一个.sql文件(比如DropFKs.sql);再把CreateFKScript列的所有语句复制出来,保存成另一个文件(比如CreateFKs.sql)。一定要核对数量,确保和你用sp_fkeys查到的30多个外键对应上,避免漏处理。
第二步:删除外键并完成表操作
- 先执行
DropFKs.sql脚本,把所有引用mytable1的外键约束删掉。执行完后可以再跑一遍sp_fkeys mytable1确认外键都没了。 - 接下来就可以放心操作表了:
- 如果是截断表:执行
TRUNCATE TABLE mytable1; - 如果是复制到另一台服务器:可以用SSMS的「导出数据」向导,或者先生成
mytable1的建表脚本,再把数据导出插入到目标服务器的对应表中。注意目标表的结构要和原表完全一致(列名、数据类型、长度等),不然后续恢复外键会报错。
- 如果是截断表:执行
第三步:恢复外键约束
完成表的截断/复制操作后,执行之前保存的CreateFKs.sql脚本,把所有外键约束重新创建回来。这里要注意两个点:
- 如果是复制表到另一台服务器,要确保
mytable1的数据已经先同步到目标服务器,再创建外键,不然会因为引用的数据不存在而失败。 - 如果是截断后重新插入数据,要先插入
mytable1的数据,再插入那些引用它的表的数据,避免外键约束验证失败。
关键注意事项
- 备份优先:操作前一定要给相关数据库做个完整备份,万一出问题可以快速回滚。
- 生产环境选低峰期:删除和创建外键会对涉及的表加锁,影响业务操作,所以尽量在业务量小的时候执行。
- 验证脚本:可以先在测试环境跑一遍整个流程,确认脚本没问题再到生产环境操作。
内容的提问来源于stack exchange,提问作者CodeMan03
相关产品推荐
相关产品推荐

