Oracle 更改生产数据库中的列数据类型

Oracle 更改生产数据库中的列数据类型,oracle,plsql,Oracle,Plsql,我正在寻找更改填充表中列的数据类型的最佳方法。Oracle只允许更改具有空值的列中的数据类型 到目前为止,我的解决方案是一个PLSQL语句,它将要修改的列的数据存储在集合中,更改表,然后在集合上迭代,恢复原始数据,并转换数据类型 -- Before: my_table ( id NUMBER, my_value VARCHAR2(255)) -- After: my_table (id NUMBER, my_value NUMBER) DECLARE TYPE record_type IS

我正在寻找更改填充表中列的数据类型的最佳方法。Oracle只允许更改具有空值的列中的数据类型

到目前为止,我的解决方案是一个PLSQL语句,它将要修改的列的数据存储在集合中,更改表,然后在集合上迭代,恢复原始数据,并转换数据类型

-- Before: my_table ( id NUMBER, my_value VARCHAR2(255))
-- After: my_table (id NUMBER, my_value NUMBER)

DECLARE
  TYPE record_type IS RECORD ( id NUMBER, my_value VARCHAR2(255));
  TYPE nested_type IS TABLE OF record_type;
  foo nested_type;
BEGIN
  SELECT id, my_value BULK COLLECT INTO foo FROM my_table;
  UPDATE my_table SET my_value = NULL;
  EXECUTE IMMEDIATE 'ALTER TABLE my_table MODIFY my_value NUMBER';
  FOR i IN foo.FIRST .. foo.LAST
  LOOP
    UPDATE my_table 
        SET  = TO_NUMBER(foo(i).my_value) 
        WHERE my_table.id = foo(i).id;
  END LOOP;
END;
/

我正在寻找一种更有经验的方法来解决这个问题。

解决方案是错误的。ALTERTABLE语句执行隐式提交。因此,解决方案存在以下问题:

  • alter table语句之后无法回滚,如果数据库在alter table语句之后崩溃,则会丢失数据
  • 在选择和更新之间,用户可以对数据进行更改

相反,您应该看看oracle online的重新定义。

您的解决方案对我来说有点危险。将这些值加载到集合中,然后从表中删除,这意味着这些值现在仅在内存中可用。如果出了什么问题,他们就输了

正确的程序是:

  • 将正确类型的列添加到表中
  • 将值复制到新列
  • 删除旧列
  • 将新列重命名为旧列名称

  • 简单的答案是,在正确执行此操作的同时,将数据库停止生产几个小时。除非你阻止人们给数据库写信,否则你永远也不能保证一切都是正确的。这个表有多大?在这段时间内,该表是否必须对应用程序可用?这是否解决了数据丢失的问题,即使其他用户对数据进行了更改,正如@steve所指出的那样?不,它没有。但是它会让你的所有数据都完好无损,这样你就可以让应用程序离线进行维护了。谢谢你,史蒂夫。事实证明,我将有一个时间窗口来进行维护,因此我将使用@Rene的方法。