我在 80 多个不同的表中有一个 ReferenceID varchar(6) 列。在分配 ID 的政府组织实现更改后,我需要将其扩展到整个数据库中的 varchar(8)。
我希望声明一个游标来获取表名,如下所示:
DECLARE @TableName AS VARCHAR(200)
DECLARE TableCursor CURSOR LOCAL READ_ONLY FOR
SELECT t.name AS TableName
FROM sys.columns c
JOIN sys.tables t ON c.object_id = t.object_id
WHERE c.name = 'ReferenceID'
OPEN TableCursor
FETCH NEXT FROM TableCursor
INTO @TableName
然后按如下方式编辑类型:
ALTER TABLE @TableName ALTER COLUMN ReferenceID VARCHAR(8)
此操作会失败,因为该列是某些表中主键的一部分(并且 PK 中包含的列因表而异)。
我真的不想为每个表手动删除并重新创建每个 PK。
在游标内,有没有办法在更改数据类型之前禁用 PK,然后重新启用它,或者在更改数据类型的任一侧删除并重新创建 PK,请记住 PK 将取决于我们当前正在查看哪个表?
最佳答案
您需要在 ALTER TABLE ... ALTER COLUMN
中显式指定 NOT NULL
,否则默认允许 NULL
。这在 PK 列中是不允许的。
以下工作正常。
CREATE TABLE p
(
ReferenceID VARCHAR(6) NOT NULL PRIMARY KEY
)
INSERT INTO p VALUES ('AAAAAA')
ALTER TABLE p ALTER COLUMN ReferenceID VARCHAR(8) NOT NULL
当省略NOT NULL
时,会出现以下错误
Msg 5074, Level 16, State 1, Line 1
The object 'PK__p__E1A99A792180FB33' is dependent on column 'ReferenceID'.
Msg 4922, Level 16, State 9, Line 1
ALTER TABLE ALTER COLUMN ReferenceID failed because one or more objects access this column.
在编程方法中需要考虑的一些事情是,您需要暂时删除引用 ReferenceID
列的任何外键,并确保不会包括当前可为空的(非 PK)ReferenceID
列的 NOT NULL
。
关于sql - 使用主键更改列数据类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11118568/