我有六个 MSSQL 2008 表的列表,我想立即从我的数据库中删除这些表。数据已完全迁移到新表中。新表中没有对旧表的引用。
问题是旧表带有大量由工具自动生成的内部 FK 约束(实际上是 aspnet_regsql)。因此,手动删除所有约束是一个真正的痛苦。
我怎样才能删除忽略所有内部约束的旧表?
我有六个 MSSQL 2008 表的列表,我想立即从我的数据库中删除这些表。数据已完全迁移到新表中。新表中没有对旧表的引用。
问题是旧表带有大量由工具自动生成的内部 FK 约束(实际上是 aspnet_regsql)。因此,手动删除所有约束是一个真正的痛苦。
我怎样才能删除忽略所有内部约束的旧表?
这取决于您要如何删除表格。如果需要删除的表列表几乎涵盖了数据库下 20% 以上的表。
然后我将在我的脚本下禁用该数据库中的所有约束并删除表并在同一脚本下启用约束。
--To Disable a Constraint at DB level
EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
--Write the code to DROP tables
DROP TABLE TABLENAME
DROP TABLE TABLENAME
DROP TABLE TABLENAME
--To Enable a Constraint at DB level
EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL'
最后要检查约束的状态,请启动此查询。
--Checks the Status of Constraints
SELECT (CASE
WHEN OBJECTPROPERTY(CONSTID, 'CNSTISDISABLED') = 0 THEN 'ENABLED'
ELSE 'DISABLED'
END) AS STATUS,
OBJECT_NAME(CONSTID) AS CONSTRAINT_NAME,
OBJECT_NAME(FKEYID) AS TABLE_NAME,
COL_NAME(FKEYID, FKEY) AS COLUMN_NAME,
OBJECT_NAME(RKEYID) AS REFERENCED_TABLE_NAME,
COL_NAME(RKEYID, RKEY) AS REFERENCED_COLUMN_NAME
FROM SYSFOREIGNKEYS
ORDER BY TABLE_NAME, CONSTRAINT_NAME,REFERENCED_TABLE_NAME, KEYNO
如果您不想在数据库级别禁用约束,请列出要删除的表。
Step1:检查与这些表关联的约束
SELECT *
FROM sys.foreign_keys
WHERE referenced_object_id = object_id('dbo.Tablename')
Step2:禁用与这些表关联的约束。
ALTER TABLE MyTable NOCHECK CONSTRAINT MyConstraint
Step3 : 删除表格
DROP TABLE TABLENAME
一个简单的DROP TABLE dbo.MyTable
将忽略所有约束(和触发器),除了外键(除非您首先删除子/引用表),您可能必须先删除这些。
编辑:评论后:
没有自动的方法。您必须遍历sys.foreign_keys
并生成一些 ALTER TABLE 语句。
运行以下脚本删除当前 DB 下所有表中的所有约束,然后运行 drop table 语句。
DECLARE @dropAllConstraints NVARCHAR(MAX) = N'';
SELECT @dropAllConstraints += N'
ALTER TABLE ' + QUOTENAME(OBJECT_SCHEMA_NAME(parent_object_id))
+ '.' + QUOTENAME(OBJECT_NAME(parent_object_id)) +
' DROP CONSTRAINT ' + QUOTENAME(name) + ';'
FROM sys.foreign_keys;
EXEC sp_executesql @dropAllConstraints
通过让 SQL 编写 SQL 来删除约束,我找到了一种合理的(ish)方法:
select concat("alter table ", table_name, " drop ", constraint_type ," ", constraint_name, ";")
from information_schema.table_constraints
where table_name like 'somefoo_%'
and
constraint_type <> "PRIMARY KEY";
您将需要修改表名以满足您的需要,或者可能选择其他列/值。
此外,这将选择任何非主键约束,这可能太大了。也许您只需将其设置为=?
我不是 DBA。可能有更好的方法可以做到这一点,但它对我的目的来说已经足够好了。
根据Jason Presley 提供的脚本,我终于找到了解决方案。此脚本会自动删除数据库中的所有约束。很容易添加 WHERE 子句,使其仅适用于相关表集。之后,删除所有表就很简单了。
我怀疑您必须在删除之前对有问题的表执行“更改”命令以删除外来键约束。
ALTER TABLE Orders DROP FOREIGN KEY fk_PerOrders;
DROP TABLE Orders;
当然,如果您先删除子表,那么您将不会遇到这个问题。(除非您有表 A 与表 B 的约束和表 B 与 A 的约束,那么您将需要更改其中一个表,例如 A 以删除约束)
例如,这不会起作用,因为 Orders 有来自 Order_Lines 的约束
DROP TABLE Orders;
DROP TABLE Order_lines;
例如,这将起作用
DROP TABLE Order_lines;
DROP TABLE Orders;