Sql server 更改大表PK列数据类型
现在我们已经用完了PK列的Sql server 更改大表PK列数据类型,sql-server,alter-table,Sql Server,Alter Table,现在我们已经用完了PK列的int容量(这是一个IDENTITY),我想这样做bigint,但是simpleALTER TABLE似乎无法处理这么大的表。所以我的问题是:如何在保持实际值不变的情况下更改PK列的类型,以及是否需要更改引用表?我认为您只能使用更改的PK数据类型创建一个新数据库,然后导出/导入数据,或者批量插入到新数据库中,然后重命名新数据库。当然,如果您有许多被引用的表,并且您的新PK数据类型与以前的PK数据类型不兼容,那么这是实际的 我们要做的是: 保存您的表 创建具有正确结构的新
int
容量(这是一个IDENTITY
),我想这样做bigint
,但是simpleALTER TABLE
似乎无法处理这么大的表。所以我的问题是:如何在保持实际值不变的情况下更改PK列的类型,以及是否需要更改引用表?我认为您只能使用更改的PK数据类型创建一个新数据库,然后导出/导入数据,或者批量插入到新数据库中,然后重命名新数据库。当然,如果您有许多被引用的表,并且您的新PK数据类型与以前的PK数据类型不兼容,那么这是实际的 我们要做的是:
保存您的表
这是干净的,可以成批进行,并且很容易理解。除了KLE的建议外,以下查询可能会有所帮助: 要禁用引用oldTable的表上的所有约束,请尝试执行以下查询的输出:
SELECT 'ALTER TABLE ' + OBJECT_NAME(fk.parent_object_id) + ' NOCHECK CONSTRAINT ' + fk.name
FROM sys.foreign_keys fk
INNER JOIN sys.foreign_key_columns AS fkc ON fk.OBJECT_ID = fkc.constraint_object_id
WHERE OBJECT_NAME (fk.referenced_object_id) = 'oldTable'
SELECT 'ALTER TABLE ' + OBJECT_NAME(fk.parent_object_id) + ' CHECK CONSTRAINT ' + fk.name
FROM sys.foreign_keys fk
INNER JOIN sys.foreign_key_columns AS fkc ON fk.OBJECT_ID = fkc.constraint_object_id
WHERE OBJECT_NAME (fk.referenced_object_id) = 'oldTable'
要将所有数据移动到新表中,并更改字段,请尝试以下操作:
INSERT INTO newTable
SELECT CONVERT(BIGINT, ID) AS ID, COL1, COL2, ..., COLN
FROM oldTable
要删除旧表,请执行以下操作:
DROP TABLE oldTable
要将新表重命名为旧名称,请执行以下操作:
sp_rename newTable, oldTable
要重新启用引用oldTable的表上的所有约束,请尝试执行以下查询的输出:
SELECT 'ALTER TABLE ' + OBJECT_NAME(fk.parent_object_id) + ' NOCHECK CONSTRAINT ' + fk.name
FROM sys.foreign_keys fk
INNER JOIN sys.foreign_key_columns AS fkc ON fk.OBJECT_ID = fkc.constraint_object_id
WHERE OBJECT_NAME (fk.referenced_object_id) = 'oldTable'
SELECT 'ALTER TABLE ' + OBJECT_NAME(fk.parent_object_id) + ' CHECK CONSTRAINT ' + fk.name
FROM sys.foreign_keys fk
INNER JOIN sys.foreign_key_columns AS fkc ON fk.OBJECT_ID = fkc.constraint_object_id
WHERE OBJECT_NAME (fk.referenced_object_id) = 'oldTable'
希望它有帮助……您还需要更改子表。毕竟,您现在也将尝试在它们中插入一个大的int。我会先把孩子们的桌子换一下 这不是一个简单或短暂的过程。我建议您告诉您的用户,数据库将在设定的日期停止维护(您可以通过执行开发所需的时间来确定需要多长时间),并在进行这些更改时将数据库重置为单用户模式。您不希望在切换到另一个表时丢失用户添加(或更改)到一个表中的数据。如果出于某种原因,您无法使用maintence窗口(我强烈建议您这样做是为了数据完整性),那么您必须首先更改子表,以避免插入错误(如果您的a非常接近限制,并且几乎会立即看到大量数据) 确保为整个datbase结构编写脚本,包括默认值、触发器、检查构造函数索引等,因为您需要重新创建所有内容
确保通过dev上的脚本完成所有这些操作。这将使您在测试完流程后更容易完成一个prod。某些数据类型不兼容。通常,您应该将所有引用的表更改为。如果您有许多被引用的表-如果使用此方法,这可能会成为“依赖地狱”,请不要忘记在表上重新创建索引,我认为最好禁用受影响表上的所有触发器