Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 更改大表PK列数据类型_Sql Server_Alter Table - Fatal编程技术网

Sql server 更改大表PK列数据类型

Sql server 更改大表PK列数据类型,sql-server,alter-table,Sql Server,Alter Table,现在我们已经用完了PK列的int容量(这是一个IDENTITY),我想这样做bigint,但是simpleALTER TABLE似乎无法处理这么大的表。所以我的问题是:如何在保持实际值不变的情况下更改PK列的类型,以及是否需要更改引用表?我认为您只能使用更改的PK数据类型创建一个新数据库,然后导出/导入数据,或者批量插入到新数据库中,然后重命名新数据库。当然,如果您有许多被引用的表,并且您的新PK数据类型与以前的PK数据类型不兼容,那么这是实际的 我们要做的是: 保存您的表 创建具有正确结构的新

现在我们已经用完了PK列的
int
容量(这是一个
IDENTITY
),我想这样做
bigint
,但是simple
ALTER TABLE
似乎无法处理这么大的表。所以我的问题是:如何在保持实际值不变的情况下更改PK列的类型,以及是否需要更改引用表?

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

我们要做的是:

保存您的表

  • 创建具有正确结构的新表

  • 禁用这些表上的所有约束以及引用这些表的约束

  • 将所有数据移动到新表中,更改字段;它可以分批完成

  • 删除空的旧表

  • 将新表重命名为旧名称

  • 在所有表上启用所有约束(某些FK列和约束可能也需要修复…但它们不是PK,因此可以修改)

    6编辑(感谢Alexey)


  • 这是干净的,可以成批进行,并且很容易理解。

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

    某些数据类型不兼容。通常,您应该将所有引用的表更改为。如果您有许多被引用的表-如果使用此方法,这可能会成为“依赖地狱”,请不要忘记在表上重新创建索引,我认为最好禁用受影响表上的所有触发器