如何删除约束列?

如何删除SQL Server 2008中具有默认约束的列?

我的查询是

alter table tbloffers drop column checkin 

我得到以下错误

ALTER TABLE DROP COLUMN checkin失败,因为一个或多个对象访问此列。

任何人都可以纠正我的查询删除约束列?

首先你应该放弃有问题的DEFAULT constraint ,之后你可以删除该列

 alter table tbloffers drop constraint [ConstraintName] go alter table tbloffers drop column checkin 

但是这个错误可能会出于其他原因,例如用户定义的函数或为其设置了SCHEMABINDING选项的视图。

UPD:完全自动删除约束脚本:

 DECLARE @sql NVARCHAR(MAX) WHILE 1=1 BEGIN SELECT TOP 1 @sql = N'alter table tbloffers drop constraint ['+dc.NAME+N']' from sys.default_constraints dc JOIN sys.columns c ON c.default_object_id = dc.object_id WHERE dc.parent_object_id = OBJECT_ID('tbloffers') AND c.name = N'checkin' IF @@ROWCOUNT = 0 BREAK EXEC (@sql) END 

这里有另外一种方法来删除默认的约束,使用一个未知的名字,而不必首先运行一个单独的查询来获取约束名称:

 DECLARE @ConstraintName nvarchar(200) SELECT @ConstraintName = Name FROM SYS.DEFAULT_CONSTRAINTS WHERE PARENT_OBJECT_ID = OBJECT_ID('__TableName__') AND PARENT_COLUMN_ID = (SELECT column_id FROM sys.columns WHERE NAME = N'__ColumnName__' AND object_id = OBJECT_ID(N'__TableName__')) IF @ConstraintName IS NOT NULL EXEC('ALTER TABLE __TableName__ DROP CONSTRAINT ' + @ConstraintName) 

在这里查询这个查询的默认约束:

 SELECT df.name 'Constraint Name' , t.name 'Table Name', c.NAME 'Column Name' FROM sys.default_constraints df INNER JOIN sys.tables t ON df.parent_object_id = t.object_id INNER JOIN sys.columns c ON df.parent_object_id = c.object_id AND df.parent_column_id = c.column_id 

这给你默认约束的名称,以及表和列的名称。

当你有这些信息时,你需要先删除默认约束:

 ALTER TABLE dbo.YourTable DROP CONSTRAINT name-of-the-default-constraint-here 

然后你可以删除列

 ALTER TABLE dbo.YourTable DROP COLUMN YourColumn 

您也可以将列及其约束放在单个语句中,而不是单独列出。

 CREATE TABLE #T ( Col1 INT CONSTRAINT UQ UNIQUE CONSTRAINT CK CHECK (Col1 > 5), Col2 INT ) ALTER TABLE #T DROP CONSTRAINT UQ , CONSTRAINT CK, COLUMN Col1 DROP TABLE #T 

一些dynamicSQL将查找相关检查约束和默认约束的名称,并将其与列一起放在下面

(但不包括其他可能的列依赖项,如外键,唯一键和主键约束,计算列,索引)

 CREATE TABLE [dbo].[TestTable] ( A INT DEFAULT '1' CHECK (A=1), B INT, CHECK (A > B) ) GO DECLARE @TwoPartTableNameQuoted nvarchar(500) = '[dbo].[TestTable]', @ColumnNameUnQuoted sysname = 'A', @DynSQL NVARCHAR(MAX); SELECT @DynSQL = 'ALTER TABLE ' + @TwoPartTableNameQuoted + ' DROP' + ISNULL(' CONSTRAINT ' + QUOTENAME(OBJECT_NAME(c.default_object_id)) + ',','') + ISNULL(check_constraints,'') + ' COLUMN ' + QUOTENAME(@ColumnNameUnQuoted) FROM sys.columns c CROSS APPLY (SELECT ' CONSTRAINT ' + QUOTENAME(OBJECT_NAME(referencing_id)) + ',' FROM sys.sql_expression_dependencies WHERE referenced_id = c.object_id AND referenced_minor_id = c.column_id AND OBJECTPROPERTYEX(referencing_id, 'BaseType') = 'C' FOR XML PATH('')) ck(check_constraints) WHERE c.object_id = object_id(@TwoPartTableNameQuoted) AND c.name = @ColumnNameUnQuoted; PRINT @DynSQL; EXEC (@DynSQL); 

我得到了同样的:

ALTER TABLE DROP COLUMN失败,因为一个或多个对象访问此列消息。

我的专栏有一个需要先删除的索引。 使用sys.indexes做了诀窍:

 DECLARE @sql VARCHAR(max) SELECT @sql = 'DROP INDEX ' + idx.NAME + ' ON tblName' FROM sys.indexes idx INNER JOIN sys.tables tbl ON idx.object_id = tbl.object_id INNER JOIN sys.index_columns idxCol ON idx.index_id = idxCol.index_id INNER JOIN sys.columns col ON idxCol.column_id = col.column_id WHERE idx.type <> 0 AND tbl.NAME = 'tblName' AND col.NAME = 'colName' EXEC sp_executeSql @sql GO ALTER TABLE tblName DROP COLUMN colName 

以下是针对SQL Azure后端(使用SQL Server Management Studio)的工作,所以YMMV,但是,如果它适合您,它比其他解决scheme更简单。

 ALTER TABLE MyTable DROP CONSTRAINT FK_MyColumn CONSTRAINT DK_MyColumn -- etc... COLUMN MyColumn GO