更改巨大的表PK列数据类型

时间:2009-09-14 07:43:47

标签: sql-server alter-table

现在我们已经耗尽了PK列上的int容量(IDENTITY)我想对bigint执行此操作,但是简单{{1}似乎无法处理那么大的表。所以我的问题是:如何在保持实际值的情况下更改PK列的类型,是否还需要更改引用表?

4 个答案:

答案 0 :(得分:4)

除了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'

要将所有数据移动到新表中,请更改字段,请尝试:

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) + ' 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'

希望它有所帮助...

答案 1 :(得分:3)

我们要做的是:

  

保存你的表格

  1. 创建一个结构正确的新表
  2. 禁用对这些表的所有约束以及引用它们的约束
  3. 将所有数据移动到新表中,并改变字段;它可以通过批次完成
  4. 删除旧表时的旧表
  5. 将新表重命名为旧名称
  6. 启用所有表的所有约束(某些FK列和约束可能也需要修复......但它们不是PK,所以它们是可修改的)

      

    6编辑(感谢Alexey)

  7. 这是干净的,可以分批进行,很好理解。

答案 2 :(得分:0)

您还需要更改子表。毕竟你现在也试图在它们中插入一个大的int。我会首先改变子表

这不是一个简单或简短的过程。我建议你告诉你的用户数据库将在设定的日期停机进行维护(你可以估算开发时间需要多长时间),并在你制作时将数据库重置为单用户模式这些变化。当您切换到另一个表时,您不希望丢失用户添加(或更改)到一个表的数据。如果因为某些原因你不能有一个维护窗口(我强烈建议你为了数据的完整性),那么你必须先改变子表,以避免插入错误,如果你的接近极限并且将是几乎立即看到大数字。

确保编写整个数据库结构的脚本,包括默认值,触发器,检查约束索引等,因为您需要重新创建所有内容。

确保通过dev上的脚本完成所有这些操作。一旦你测试了这个过程,这将使得更容易做一个prod。

答案 3 :(得分:-1)

我认为您只能创建一个具有更改的PK数据类型的新数据库,然后导出/导入数据,或批量插入到新数据库,然后重命名新数据库。当然这是实际的,如果您有许多引用的表,并且您的新PK数据类型与以前不兼容。