我有这个脚本在sql server 2005中运行
-- t-sql scriptlet to drop all constraints on a table
DECLARE @database nvarchar(50)
DECLARE @table nvarchar(50)
set @database = 'dotnetnuke'
set @table = 'tabs'
DECLARE @sql nvarchar(255)
WHILE EXISTS(select * from INFORMATION_SCHEMA.TABLE_CONSTRAINTS where constraint_catalog = @database and table_name = @table)
BEGIN
select @sql = 'ALTER TABLE ' + @table + ' DROP CONSTRAINT ' + CONSTRAINT_NAME
from INFORMATION_SCHEMA.TABLE_CONSTRAINTS
where constraint_catalog = @database and
table_name = @table
exec sp_executesql @sql
END
它在SQL Server 2008中不起作用。如何轻松删除某个表的所有外键约束?有人有更好的剧本吗?
答案 0 :(得分:7)
有一种更简单的方法。 那为什么呢? 脚本:
`select ' alter table ' + schema_name(Schema_id)+'.'+ object_name(parent_object_id)
+ ' DROP CONSTRAINT ' + name from sys.foreign_keys f1`
将为所有外键编写drop的脚本
答案 1 :(得分:1)
我注意到您没有在原始查询中过滤外键。此外,您无法过滤数据库名称上的INFORMATION_SCHEMA视图,因为它们将始终返回当前数据库。而是尝试这样的事情:
修改强>
从评论中,您说您正在尝试删除指定表上的所有外键和指向同一个表的所有外键,以便您可以删除该表。我已经调整了例程来做到这一点。我建议你调整问题以反映这一点。应该注意的是,所有真正需要的是删除指向相关表的外键(联合中的第二个查询),因为当表被删除时,表本身的任何约束都将被删除。
Declare @Database nvarchar(128)
Declare @ConstraintName nvarchar(128)
Declare @TableName nvarchar(128)
Declare @BaseSql nvarchar(max)
Declare @Sql nvarchar(max)
Declare @Tables Cursor
Set @Database = 'dotnetnuke'
Set @TableName = 'tabs'
Set @BaseSQL = 'Use DATABASENAME; Alter Table TABLENAME Drop Constraint CONSTRAINTNAME'
Set @Tables = Cursor Fast_Forward For
Select TABLE_NAME, CONSTRAINT_NAME
From INFORMATION_SCHEMA.TABLE_CONSTRAINTS
Where CONSTRAINT_CATALOG = @Database
And TABLE_NAME = @TableName
And CONSTRAINT_TYPE = 'FOREIGN KEY'
Union All
Select FK.TABLE_NAME, RC.CONSTRAINT_NAME
From INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS As RC
Join INFORMATION_SCHEMA.TABLE_CONSTRAINTS As TC
On TC.CONSTRAINT_NAME = RC.UNIQUE_CONSTRAINT_NAME
And TC.TABLE_NAME = @TableName
Join INFORMATION_SCHEMA.TABLE_CONSTRAINTS As FK
On FK.CONSTRAINT_NAME = RC.CONSTRAINT_NAME
Open @Tables
Fetch Next From @Tables Into @TableName, @ConstraintName
While @@Fetch_Status = 0
Begin
Set @Sql = Replace(@BaseSql, 'DATABASENAME', Quotename(@Database))
Set @Sql = Replace(@Sql, 'TABLENAME', Quotename(@TableName))
Set @Sql = Replace(@Sql, 'CONSTRAINTNAME', Quotename(@ConstraintName))
Exec(@Sql)
Fetch Next From @Tables Into @TableName, @ConstraintName
End
Close @Tables
Deallocate @Tables
答案 2 :(得分:0)
编写的脚本假定您在包含要删除的对象的数据库中运行它。您是从另一个数据库(例如master或tempdb)运行它吗?也许您的默认(登录时)数据库已更改?
(我在其中一个数据库上尝试时也注意到它不考虑模式。这可能值得在一段时间内添加。)
答案 3 :(得分:0)
这是相当古老的帖子,但可能有助于某人。
从John Paul Cook的这篇文章中获取代码的核心:Script to create all foreign keys
我已经对代码进行了一些修改,因此我们可以按表(变量@TARGET_TABLE
)和模式(变量@TARGET_SCHEMA
)名称进行过滤。
我不得不修改脚本,以便它还打印其他表拥有的那些外键的脚本,引用@TARGET_TABLE
。
您必须设置脚本开头的以下三个变量:
<强>说明:强>
脚本如下所示:
-- User variables
DECLARE @TARGET AS VARCHAR(10); -- SET to 'DROP' or 'CREATE'
DECLARE @TARGET_TABLE AS SYSNAME; -- TABLE WHOSE FOREIGN-KEY WILL BE SCRIPTED
DECLARE @TARGET_SCHEMA AS SYSNAME; -- SCHEMA OF THE TABLE
SET @TARGET = 'DROP';
SET @TARGET_SCHEMA = 'dbo';
SET @TARGET_TABLE = 'tabs';
-- Other variables
DECLARE @schema_name sysname;
DECLARE @table_name sysname;
DECLARE @constraint_name sysname;
DECLARE @constraint_object_id int;
DECLARE @referenced_object_name sysname;
DECLARE @is_disabled bit;
DECLARE @is_not_for_replication bit;
DECLARE @is_not_trusted bit;
DECLARE @delete_referential_action tinyint;
DECLARE @update_referential_action tinyint;
DECLARE @tsql nvarchar(4000);
DECLARE @tsql2 nvarchar(4000);
DECLARE @fkCol sysname;
DECLARE @pkCol sysname;
DECLARE @col1 bit;
DECLARE FKcursor CURSOR FOR
(
SELECT
OBJECT_SCHEMA_NAME(parent_object_id)
, OBJECT_NAME(parent_object_id)
, name
, OBJECT_NAME(referenced_object_id)
, object_id
, is_disabled, is_not_for_replication, is_not_trusted
, delete_referential_action, update_referential_action
FROM
sys.foreign_keys
WHERE
OBJECT_NAME(parent_object_id) = @TARGET_TABLE
AND
OBJECT_SCHEMA_NAME(parent_object_id) = @TARGET_SCHEMA
)
UNION ALL
(
SELECT
OBJECT_SCHEMA_NAME(parent_object_id)
, OBJECT_NAME(parent_object_id)
, name
, OBJECT_NAME(referenced_object_id)
, object_id
, is_disabled, is_not_for_replication, is_not_trusted
, delete_referential_action, update_referential_action
FROM
sys.foreign_keys
WHERE
OBJECT_NAME(referenced_object_id) = @TARGET_TABLE
AND
OBJECT_SCHEMA_NAME(parent_object_id) = @TARGET_SCHEMA
)
ORDER BY 1,2;
OPEN FKcursor;
FETCH NEXT FROM FKcursor INTO @schema_name, @table_name, @constraint_name
, @referenced_object_name, @constraint_object_id
, @is_disabled, @is_not_for_replication, @is_not_trusted
, @delete_referential_action, @update_referential_action;
WHILE @@FETCH_STATUS = 0
BEGIN
IF @TARGET <> 'CREATE'
SET @tsql = 'ALTER TABLE '
+ QUOTENAME(@schema_name) + '.' + QUOTENAME(@table_name)
+ ' DROP CONSTRAINT ' + QUOTENAME(@constraint_name) + ';';
ELSE
BEGIN
SET @tsql = 'ALTER TABLE '
+ QUOTENAME(@schema_name) + '.' + QUOTENAME(@table_name)
+ CASE @is_not_trusted
WHEN 0 THEN ' WITH CHECK '
ELSE ' WITH NOCHECK '
END
+ ' ADD CONSTRAINT ' + QUOTENAME(@constraint_name)
+ ' FOREIGN KEY ('
SET @tsql2 = '';
DECLARE ColumnCursor CURSOR FOR
select COL_NAME(fk.parent_object_id, fkc.parent_column_id)
, COL_NAME(fk.referenced_object_id, fkc.referenced_column_id)
from sys.foreign_keys fk
inner join sys.foreign_key_columns fkc
on fk.object_id = fkc.constraint_object_id
where fkc.constraint_object_id = @constraint_object_id
order by fkc.constraint_column_id;
OPEN ColumnCursor;
SET @col1 = 1;
FETCH NEXT FROM ColumnCursor INTO @fkCol, @pkCol;
WHILE @@FETCH_STATUS = 0
BEGIN
IF (@col1 = 1)
SET @col1 = 0
ELSE
BEGIN
SET @tsql = @tsql + ',';
SET @tsql2 = @tsql2 + ',';
END;
SET @tsql = @tsql + QUOTENAME(@fkCol);
SET @tsql2 = @tsql2 + QUOTENAME(@pkCol);
FETCH NEXT FROM ColumnCursor INTO @fkCol, @pkCol;
END;
CLOSE ColumnCursor;
DEALLOCATE ColumnCursor;
SET @tsql = @tsql + ' ) REFERENCES ' + QUOTENAME(@schema_name) + '.' + QUOTENAME(@referenced_object_name)
+ ' (' + @tsql2 + ')';
SET @tsql = @tsql
+ ' ON UPDATE ' + CASE @update_referential_action
WHEN 0 THEN 'NO ACTION '
WHEN 1 THEN 'CASCADE '
WHEN 2 THEN 'SET NULL '
ELSE 'SET DEFAULT '
END
+ ' ON DELETE ' + CASE @delete_referential_action
WHEN 0 THEN 'NO ACTION '
WHEN 1 THEN 'CASCADE '
WHEN 2 THEN 'SET NULL '
ELSE 'SET DEFAULT '
END
+ CASE @is_not_for_replication
WHEN 1 THEN ' NOT FOR REPLICATION '
ELSE ''
END
+ ';';
END;
PRINT @tsql;
IF @TARGET = 'CREATE'
BEGIN
SET @tsql = 'ALTER TABLE '
+ QUOTENAME(@schema_name) + '.' + QUOTENAME(@table_name)
+ CASE @is_disabled
WHEN 0 THEN ' CHECK '
ELSE ' NOCHECK '
END
+ 'CONSTRAINT ' + QUOTENAME(@constraint_name)
+ ';';
PRINT @tsql;
END;
FETCH NEXT FROM FKcursor INTO @schema_name, @table_name, @constraint_name
, @referenced_object_name, @constraint_object_id
, @is_disabled, @is_not_for_replication, @is_not_trusted
, @delete_referential_action, @update_referential_action;
END;
CLOSE FKcursor;
DEALLOCATE FKcursor;
答案 4 :(得分:-3)
[T-SQL]删除表格上的所有约束
http://weblogs.asp.net/jgalloway/archive/2006/04/12/442616.aspx
-- t-sql scriptlet to drop all constraints on a table
DECLARE @database nvarchar(50)
DECLARE @table nvarchar(50)
set @database = 'dotnetnuke'
set @table = 'tabs'
DECLARE @sql nvarchar(255)
WHILE EXISTS(select * from INFORMATION_SCHEMA.TABLE_CONSTRAINTS where constraint_catalog = @database and table_name = @table)
BEGIN
select @sql = 'ALTER TABLE ' + @table + ' DROP CONSTRAINT ' + CONSTRAINT_NAME
from INFORMATION_SCHEMA.TABLE_CONSTRAINTS
where constraint_catalog = @database and
table_name = @table
exec sp_executesql @sql
END