我创建了一个表:
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
列名或提供的数量 值与表定义不匹配。
为什么我收到此错误?
答案 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
列,但这不是规则的例外(我认为不应该允许它,因为它具有误导性)。