如何改变复合主键中varchar的长度?

时间:2010-01-11 16:48:38

标签: sql-server sql-server-2005 sql-server-2008 primary-key constraints

在MSSQL中,我有一个像这样创建的表:

CREATE TABLE [mytable] (fkid int NOT NULL, data varchar(255) CONSTRAINT DF_mytable_data DEFAULT '' NOT NULL);
ALTER TABLE [mytable] ADD CONSTRAINT PK_mytable_data PRIMARY KEY (fkid, data);

现在我想将'data'列的长度从255增加到4000.

如果我只是尝试:

ALTER TABLE [mytable] ALTER COLUMN data varchar(4000);

然后我收到此错误:

The object 'PK_mytable_data' is dependent on the column 'data'

如果我试试这个:

ALTER TABLE [mytable] DROP CONSTRAINT PK_mytable_data;
ALTER TABLE [mytable] ALTER COLUMN data varchar(4000);
ALTER TABLE [mytable] ADD CONSTRAINT PK_mytable_data PRIMARY KEY (fkid, data);

然后我收到此错误:

Cannot define PRIMARY KEY constraint on nullable column in table 'mytable'

我错过了什么?这两列都是用NOT NULL定义的,那么为什么MSSQL报告它放弃之后无法重新创建这个约束呢?

谢谢! 埃文

3 个答案:

答案 0 :(得分:20)

通过将数据类型更改为varchar(4000),您可以接受NULLs

试试这个:

ALTER TABLE [mytable] DROP CONSTRAINT PK_mytable_data;
ALTER TABLE [mytable] ALTER COLUMN data varchar(4000) NOT NULL;
ALTER TABLE [mytable] ADD CONSTRAINT PK_mytable_data PRIMARY KEY (fkid, data);

请注意,索引大小(隐式为PK创建)限制为900个字节,更大值的插入将失败。

答案 1 :(得分:3)

你不必放弃约束,只需检查它

IF EXISTS 
(SELECT 1 FROM sys.tables tab INNER JOIN sys.columns col ON tab.object_id = col.object_id      WHERE tab.name = 'MY_TABLE' AND col.name = 'MY_COLUMN')

BEGIN

ALTER TABLE MY_TABLE NOCHECK CONSTRAINT ALL
ALTER TABLE [dbo].[MY_TABLE] ALTER COLUMN [MY_COLUMN] VARCHAR(50) NOT NULL;
ALTER TABLE MY_TABLE CHECK CONSTRAINT ALL

END

GO
**请注意,这只会在'增加'意义上起作用,但它不能用于减小尺寸,因为它可能会导致主键约束违规(想想如果你有两个数据单元AAB和AAC,那么你将大小减小一个。)对于这种情况,您必须删除约束,但是在您有一些sql之前不会将数据存储在临时表中检查以确保它适合您的新更改列而没有重复,然后更新回新的更改表列。

答案 2 :(得分:2)

如果在最后创建此索引时收到警告,请不要感到惊讶,您可能会创建一个大于允许的900字节的索引键。 (因为PK将是聚集索引(默认)或强制执行它的NC索引。)