更改SQL Server中

时间:2016-06-21 08:08:02

标签: sql-server database sql-server-2008 tsql

我们有一个SQL Server 2008数据库,其中包含一个包含超过14亿条记录的表。由于坐标系的调整,我们必须将坐标列的数据类型从decimal(18, 2)扩展为decimal(18, 3)

我们已经尝试了多项内容,但在执行约14个小时后,所有内容都导致异常(事务日志已满)。

这些是我们尝试过的事情:

  1. 更改表格

    ALTER TABLE Adress
    ALTER COLUMN Coordinate decimal(18, 3) NULL
    
  2. 设计

    • 取消选中Tools > Options > Designer > Prevent saving changes that require table re-creation
    • 打开设计器
    • 将列的数据类型更改为decimal(18, 3)
    • Right-click > Generate Change Script...
  3. 这个脚本的作用是创建一个包含新数据类型的新表,将旧数据复制到新表,删除旧表并重命名新表。

    不幸的是,两次尝试都会在执行14小时后导致事务日志完全异常。

    我想,通过ALTER TABLE... ALTER COLUMN...更改数据类型只会更改元数据,应该在(毫秒)内完成?

    • 你知道我可以尝试的其他方法吗?
    • 为什么我的尝试(特别是#1)需要那么多时间?

    提前致谢

4 个答案:

答案 0 :(得分:3)

好主要问题似乎是将大量数据保存到表中。你的两次尝试似乎都很好。他们两个肯定会花时间我必须说因为数据很大。

每次更改列数据类型时, SQL SERVER 会尝试将现有数据转换为目标数据类型。处理大量数据的转换可能会导致执行延迟。

此外,我想知道你桌上是否有 触发器

嘛!最后我建议你按照步骤进行操作。至少尝试一下

  1. 删除指向旧列的所有主键/索引/约束,并禁用任何触发器(如果有)。
  2. 使用新数据类型引入新的可空列(即使 它对于表来说是非空的)。
  3. 现在在表上进行更新查询,将新列值设置为旧列值。您可以在更新1000/100000批次记录时更新数据块。此外,您还可以为查询应用条件以获得更好的结果。
  4. 通过将新列值设置为旧列来更新所有表格,然后从设计器中删除 NULL 字符为 NOT NULL (如果它意味着为NOT NULL )。
  5. 删除/删除旧列。执行选择查询并验证您的更改。
  6. 我应该添加的最后一点是您的数据库事务日志也已满,可以缩小但有一些预防措施。 Here是如何重置事务日志的非常好的示例。也应该看看这个。

    希望这有助于。 :)

答案 1 :(得分:1)

解决方案是批量更新,缓解日志文件的压力。

方法1:
a)使用新定义创建一个新表 b)批量复制数据到新表 c)放下旧桌子 d)重命名新表。

方法2:
a)使用正确的定义创建一个新列 b)批量更新旧列中的数据 c)放下旧栏目 d)重命名新列。

方法3:
a)将数据BCP到文件中 b)截断表格 c)改变色谱柱 d)将恢复模型设置为批量记录或简单 e)将文件中的数据BCP到表中 f)将恢复模型设置回完整。

答案 2 :(得分:0)

这是我的建议: 在表格中添加一个字段,并将其命名如下:

NewCoordinate DECIMAL(18,3)NULL

WHILE(1 = 1)
BEGIN
    UPDATE TOP(1000) Adress SET NewCoordinate = Coordinate
    WHERE NewCoordinate IS NULL
      IF (@@ROWCOUNT < 1000)    
    BREAK    
END

尽量让您的交易保持小规模。

最后放弃你的坐标字段。

答案 3 :(得分:0)

添加新列作为最后一列
如果您尝试在最后一列之前插入,则可能需要很长时间 NewCoordinate decimal(18,3)NULL

select 1 
while(@@rowcount > 0) 
BEGIN
    UPDATE TOP(10000) Adress 
    SET   NewCoordinate  = Coordinate
    WHERE NewCoordinate <> Coordinate
END