编程修改主键列长度后重新添加主键报错问题排查
问题原因及解决方法
错误根源
你最后一行执行的ALTER TABLE table1 ADD PRIMARY KEY(PRIMARYKEYCOLUMN)中,PRIMARYKEYCOLUMN是临时表@PKs的列名,并非table1实际存在的主键列名(比如你的Col1)。SQL Server会将其视为table1的列去查找,自然找不到对应列,因此抛出1911错误。
修正步骤
你需要从@PKs中取出实际的主键列名,通过动态SQL执行添加主键的操作,具体如下:
- 从临时表中获取真实的主键列名:
DECLARE @PKColumn varchar(100) = (SELECT TOP 1 PRIMARYKEYCOLUMN FROM @PKs)
(注:如果是复合主键,需要拼接多个列名,这里默认你是单字段主键)
- 动态构建添加主键的SQL语句(建议指定约束名,方便后续维护):
DECLARE @AddPKCmd varchar(200) = 'ALTER TABLE table1 ADD CONSTRAINT PK_table1_' + @PKColumn + ' PRIMARY KEY(' + @PKColumn + ')' EXECUTE (@AddPKCmd)
完整修正后的代码
DECLARE @Col1Len int = (SELECT character_maximum_length FROM information_schema.columns WHERE table_name = 'table1' AND column_name = 'Col1') IF (@Col1Len < 60) BEGIN DECLARE @PKs TABLE (PRIMARYKEYCOLUMN varchar(100)) INSERT INTO @PKs (PRIMARYKEYCOLUMN) ( SELECT column_name AS PRIMARYKEYCOLUMN FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KU ON TC.CONSTRAINT_TYPE = 'PRIMARY KEY' AND TC.CONSTRAINT_NAME = KU.CONSTRAINT_NAME AND KU.table_name = 'table1') -- 获取真实主键列名 DECLARE @PKColumn varchar(100) = (SELECT TOP 1 PRIMARYKEYCOLUMN FROM @PKs) -- 改用新系统视图获取主键约束名,兼容性更好 DECLARE @PK varchar(100) = (SELECT kc.name FROM sys.key_constraints kc JOIN sys.tables t ON kc.parent_object_id = t.object_id WHERE kc.type = 'PK' AND t.name = 'table1') DECLARE @Command varchar(100) = 'ALTER TABLE table1 DROP CONSTRAINT ' + @PK EXECUTE (@Command) ALTER TABLE table1 ALTER COLUMN Col1 varchar(40) NOT NULL -- 动态添加主键 DECLARE @AddPKCmd varchar(200) = 'ALTER TABLE table1 ADD CONSTRAINT PK_table1_' + @PKColumn + ' PRIMARY KEY(' + @PKColumn + ')' EXECUTE (@AddPKCmd) END
额外优化点
- 将
@Col1Len的类型从varchar(100)改为int,避免字符串与数字比较的潜在问题; - 替换旧系统视图
sysobjects为sys.key_constraints+sys.tables,适配SQL Server新版本的兼容性要求。
内容的提问来源于stack exchange,提问作者Carlos M
相关产品推荐
相关产品推荐

