更改 Oracle 中数字列的精度

问题描述 投票:0回答:4

目前我有一列被声明为数字。我想将列的精度更改为 NUMBER(14,2)。

所以,我运行了命令

 alter table EVAPP_FEES modify AMOUNT NUMBER(14,2)'

为此,我收到了一个错误:

   column to be modified must be empty to decrease precision or scale

我猜测它希望在改变精度时该列为空,我不知道为什么它说我们要在增加精度时减少它,列中的数据不能丢失。有没有一个简短的解决方法?我不想将其复制到另一个表中然后将其删除,或者重命名列并在列之间进行复制,因为在传输和删除之间存在丢失数据的风险。

sql oracle precision
4个回答
99
投票

假设您最初没有设置精度,则假定为最大值 (38)。您正在降低精度,因为您将其从 38 更改为 14。

处理此问题的最简单方法是重命名列,复制数据,然后删除原始列:

alter table EVAPP_FEES rename column AMOUNT to AMOUNT_OLD;

alter table EVAPP_FEES add AMOUNT NUMBER(14,2);

update EVAPP_FEES set AMOUNT = AMOUNT_OLD;

alter table EVAPP_FEES drop column AMOUNT_OLD;

如果您确实想保留列顺序,可以将数据移动两次:

alter table EVAPP_FEES add AMOUNT_TEMP NUMBER(14,2);

update EVAPP_FEES set AMOUNT_TEMP = AMOUNT;

update EVAPP_FEES set AMOUNT = null;

alter table EVAPP_FEES modify AMOUNT NUMBER(14,2);

update EVAPP_FEES set AMOUNT = AMOUNT_TEMP;

alter table EVAPP_FEES drop column AMOUNT_TEMP;

1
投票

通过设置比例,您会降低精度。尝试 NUMBER(16,2)。


1
投票

如果表被压缩,这将起作用:

alter table EVAPP_FEES add AMOUNT_TEMP NUMBER(14,2);

update EVAPP_FEES set AMOUNT_TEMP = AMOUNT;

update EVAPP_FEES set AMOUNT = null;

alter table EVAPP_FEES modify AMOUNT NUMBER(14,2);

update EVAPP_FEES set AMOUNT = AMOUNT_TEMP;

alter table EVAPP_FEES move nocompress;

alter table EVAPP_FEES drop column AMOUNT_TEMP;

alter table EVAPP_FEES compress;

0
投票

我认为更好的方法是创建一个临时表并将所有数据复制到其中并更改类型然后恢复数据:

create table EVAPP_FEES_temp as select * from EVAPP_FEES;
-- disable foreign keys to this table
delete EVAPP_FEES;
alter table EVAPP_FEES modify AMOUNT NUMBER(14,2);
insert into EVAPP_FEES select * from EVAPP_FEES_temp;
-- enable foreign keys to this table
drop table EVAPP_FEES_temp;
© www.soinside.com 2019 - 2024. All rights reserved.