删除具有默认约束的列

时间:2012-05-16 13:13:30

标签: sql-server-2005

我创建了一个表:

create table userTable
(
    userId int identity(1,1) not null,
    userName nvarchar(20) not null,
    joinDate datetime not null default getdate()
        constraint pk_userTable primary key(userId) on [primary]

)

然后我尝试删除列joinDate:

alter table userTable drop column joinDate

但是我得到了错误:

  

Msg 5074,Level 16,State 1,Line 1
  对象'DF_userTable_joinD_31EC6D26'取决于列'joinDate'。
  Msg 4922,Level 16,State 9,Line 1
  ALTER TABLE DROP COLUMN joinDate失败,因为一个或多个对象   访问此列。

为什么会这样?

另外,我想在插入新行时仅为userName列指定值,但是当我尝试这样做时:

INSERT userTable SELECT 'name1';

我收到错误消息:

  

Msg 213,Level 16,State 1,Line 1
列名或提供的数量   值与表定义不匹配。

为什么我收到此错误?

1 个答案:

答案 0 :(得分:1)

如果要删除列,首先需要删除约束。由于您没有为命名约束而烦恼,因此您需要找到它(例如,如果您没有在收到的错误消息中注意到它)。

DECLARE @sql NVARCHAR(4000);

SELECT @sql = 'ALTER TABLE userTable DROP CONSTRAINT ' + QUOTENAME(dc.name) + ';'
  FROM sys.default_constraints AS dc
  INNER JOIN sys.columns AS c
  ON dc.parent_object_id = c.[object_id]
  AND dc.parent_column_id = c.column_id
  WHERE parent_object_id = OBJECT_ID('dbo.userTable')
  AND c.name = 'joinDate';

PRINT @sql;
-- EXEC sp_executesql @sql;
-- ALTER TABLE userTable DROP COLUMN joinDate;

修改

如果您要插入此表而不对joinDate列进行硬编码,则不能只说:

INSERT userTable SELECT 'name1';

您将收到列列表与表定义或类似内容不匹配的错误。因此,如果要插入列的子集,则需要命名这些列。

INSERT userTable(userName) SELECT 'name1';

懒惰并且遗漏列列表适用于IDENTITY列,但这不是规则的例外(我认为不应该允许它,因为它具有误导性)。