Sql 如何使用数据更改列的数据类型
假设我有一个表Sql 如何使用数据更改列的数据类型,sql,oracle,Sql,Oracle,假设我有一个表call\u log,其中有一列名为duration。让我们进一步假设,当我将表放在一起时,我犯了一个错误,将duration设置为varchar列而不是数字。现在我无法对该列进行正确排序。我想重命名该列,以便发布 ALTER TABLE call_log MODIFY (duration NUMBER); 但是我得到 ORA-01439: column to be modified must be empty to change datatype. 我的表已被使用,并且有数据
call\u log
,其中有一列名为duration
。让我们进一步假设,当我将表放在一起时,我犯了一个错误,将duration
设置为varchar列而不是数字。现在我无法对该列进行正确排序。我想重命名该列,以便发布
ALTER TABLE call_log MODIFY (duration NUMBER);
但是我得到
ORA-01439: column to be modified must be empty to change datatype.
我的表已被使用,并且有数据!我不想丢失数据。如何修改列的数据类型而不丢失数据?使用正确的数据类型创建临时列,将数据复制到新列,删除旧列,重命名新列以匹配旧列的名称
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;
这个答案的想法来源于。前面的解决方案非常好,但是如果您不想更改call_log table结构中的列顺序,则以下步骤适用于此:
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;
注1:在表调用日志中将主键更改为主键
注2:此解决方案假设您的数据大小不大。或者一些限制,我无法使用前两种解决方案:
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;
保留原始列顺序的最佳解决方案:创建临时列,将数据复制到临时列,将原始列设置为null,修改其类型,将临时列中的数据设置回临时列,然后删除临时列:
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);
请对评论投赞成票。我一次性执行了上一个解决方案,但由于某些原因,它没有按预期工作。我丢失了该列的所有信息,无法回滚。下次我肯定会逐行执行并检查以确保。。。