如何删除具有约束的列?

Rob*_*rai 126 sql-server sql-server-2008

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

我的疑问是

alter table tbloffers
drop column checkin
Run Code Online (Sandbox Code Playgroud)

我收到了以下错误

ALTER TABLE DROP COLUMN签入失败,因为一个或多个对象访问此列.

任何人都可以更正我的查询以删除具有约束的列吗?

Ole*_*Dok 221

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

alter table tbloffers drop constraint [ConstraintName]
go

alter table tbloffers drop column checkin
Run Code Online (Sandbox Code Playgroud)

但错误可能出于其他原因 - 例如用户定义的函数或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
Run Code Online (Sandbox Code Playgroud)


Chr*_*row 118

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

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)
Run Code Online (Sandbox Code Playgroud)

  • 确实很好的答案.为了方便/将来使用,我制作了一个存储过程:http://pastebin.com/2CeXZDh2 (7认同)

Mar*_*ith 24

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

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 
Run Code Online (Sandbox Code Playgroud)

将查找依赖检查约束和默认约束的名称并将其与列一起删除的一些动态SQL如下所示

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

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); 
Run Code Online (Sandbox Code Playgroud)


mar*_*c_s 23

在此处使用此查询查找默认约束:

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
Run Code Online (Sandbox Code Playgroud)

这将为您提供默认约束的名称,以及表和列名称.

获得该信息后,首先需要删除默认约束:

ALTER TABLE dbo.YourTable
DROP CONSTRAINT name-of-the-default-constraint-here
Run Code Online (Sandbox Code Playgroud)

然后你可以删除列

ALTER TABLE dbo.YourTable DROP COLUMN YourColumn
Run Code Online (Sandbox Code Playgroud)

  • 它不必按顺序完成.你可以同时做这两件事. (2认同)