如何使用数据更改列的数据类型

时间:2014-04-18 14:24:05

标签: sql oracle

假设我有一个表call_log,其中有一个名为duration的列。让我们进一步假装当我把表放在一起时,我错误地将duration变为varchar列而不是数字。现在我无法正确排序该列。我想重命名列,以便发出...

ALTER TABLE call_log MODIFY (duration NUMBER);

但我明白了......

ORA-01439: column to be modified must be empty to change datatype.

我的桌子一直在使用并且有数据!而且我不想丢失数据。如何在不丢失数据的情况下修改列的数据类型?

4 个答案:

答案 0 :(得分:12)

使用正确的数据类型创建临时列,将数据复制到新列,删除旧列,重命名新列以匹配旧列的命名。

ALTER TABLE call_log ADD (duration_temp NUMBER);
UPDATE call_log SET duration_temp = duration;
ALTER TABLE call_log DROP COLUMN duration;
ALTER TABLE call_log RENAME COLUMN duration_temp TO duration;

这个答案的想法来自Oracle's forums

答案 1 :(得分:2)

之前的解决方案非常好,但是如果您不想更改call_log表结构中的列顺序,那么以下步骤适用于此:

create table temp_call_log  as select * from call_log; /* temp backup table for call_log */
UPDATE call_log SET duration = null;
/*check,... be sure.... then commit*/
commit;
ALTER TABLE call_log MODIFY duration NUMBER;
UPDATE call_log c SET c.duration = (select t.duration from temp_call_log t where t.primarykey_comumn = c.primarykey_column);
/*check,... be sure.... then commit*/
commit;
drop table temp_call_log;

note1:使用表call_log中的主键更改primarykey_comumn。

note2:此解决方案假设您的数据量不大。

答案 2 :(得分:2)

保留列原始顺序的最佳解决方案:创建一个临时列,将数据复制到该列,将原始列设置为null,修改其类型,将数据从temp列设置回该列,然后删除temp列:

ALTER TABLE call_log ADD duration_temp NUMBER;
UPDATE call_log SET duration_temp = duration;
UPDATE call_log SET duration = NULL;
ALTER TABLE call_log MODIFY duration NUMBER;
UPDATE call_log SET duration = duration_temp;
ALTER TABLE call_log DROP (duration_temp);

答案 3 :(得分:0)

或某些约束,我无法使用前两种解决方案:

CREATE TABLE call_log_temp AS (SELECT * FROM call_log where rownum = 0);
ALTER TABLE call_log_temp MODIFY duration NUMBER;
INSERT INTO call_log_temp( id, duration, and_all_other_columns, ... )
  SELECT id, duration, and_all_other_columns, ...
  FROM call_log;  
DROP TABLE call_log;    
ALTER TABLE call_log_temp RENAME TO call_log;