我有一个表,其中一列是Number(22,12),其中应该是Number(22,2)。由于其中包含数据,因此我不能仅将列修改为正确的精度。
修复专栏的最有效方法是什么?
之前我没有提到的一件事是该表有几个索引,触发器并链接到其他表。
答案 0 :(得分:5)
ALTER TRIGGER trfoobar DISABLE;
ALTER TABLE foobar ADD (newcol number);
UPDATE foobar SET newcol=oldcol, oldcol=null;
ALTER TABLE foobar MODIFY(oldcol number(22,2));
UPDATE foobar SET oldcol=newcol;
ALTER TABLE foobar DROP(newcol);
ALTER TRIGGER trfoobar ENABLE;
答案 1 :(得分:2)
如果您需要在转换期间使表联机,并且您具有数据库所需的权限,则可以使用DBMS_REDEFINITION。此链接包含更多信息。 http://www.psoug.org/reference/dbms_redefinition.html
如果您不需要将表联机,最简单的方法是添加具有新数据类型的列,复制数据,然后删除原始列。如果您需要列的顺序相同,则可以创建原始表的视图。
如果您不想使用视图,可以创建一个新表,复制数据,删除旧表,然后重命名新表。
答案 2 :(得分:0)
您可以导出数据,删除表,重新创建和导入或
使用正确的定义创建一个新表,然后执行:
INSERT / * + append * / INTO new_table(SELECT * FROM old_table);
删除旧表,然后将新表重命名为旧表。
ALTER TABLE new_table RENAME TO old_table;
答案 3 :(得分:0)
我总是尽量避免使用重命名表 - >创建新表 - >做一些事情来移动数据 - >尽可能丢弃旧表解决方案。总是会考虑PL / SQL失效,重新创建授权,锁等等,这会使这个问题复杂化。
如果触发器没有引用所涉及的列,我会:
这样做的一个小缺点是,当开发工具描述表时,新列将出现在表列列表的末尾 - 这从来没有困扰过我,但它对某些人来说很重要。
正如Daniel E.所指出的那样,DBMS_REDEFINITION软件包可以替代它,但根据我的经验,正确设置和执行这项工作非常耗时。如果您必须在绝对没有停机时间的情况下对系统进行在线更改,那么学习这种技术是值得的。