在修改表字段的NUMBER類型的精度或刻度時,你可能會遇到ORA-01440: column to be modified must be empty to decrease precision or scale,下面介紹一下,如何處理這個問題。測試案例如下:
SQL> drop table test;
Table dropped.
SQL>create table test(product_id number, price number(38,1));
Table created.
SQL> insert into test
2 select 1001, 18.2 from dual union all
3 select 1002, 38.5 from dual union all
4 select 1003, 34.8 from dual union all
5 select 1004, 87.4 from dual;
4 rows created.
SQL> commit;
Commit complete.
SQL> alter table test modify price number(38,2);
alter table test modify price number(38,2)
*
ERROR at line 1:
ORA-01440: column to be modified must be empty to decrease precision or scale
SQL>
如上所示,當我們修改字段price的NUMBEr類型的刻度時,就會遇到ORA-01440: column to be modified must be empty to decrease precision or scale,解決這個問題的方法有兩種
方案1:
1:首先對該表做邏輯備份,當然如果你確定沒有什么問題,也可以忽略此步驟。作為DBA,一般都應該有強烈的風險意識。
SQL> create table test_20170608_bak
2 as
3 select * from test;
Table created.
SQL>
2:增加一個臨時字段用來復制舊字段數據
SQL> alter table test add price_tmp number(38,1);
Table altered.
SQL> update test set price_tmp = price;
4 rows updated.
SQL> commit;
Commit complete.
3:修改字段price的刻度(Scale)值
SQL> update test set price = null;
4 rows updated.
SQL> commit;
Commit complete.
SQL> alter table test modify price number(38,2);
Table altered.
4:將數據從字段price_tmp更新回price字段
SQL> update test set price = price_tmp;
4 rows updated.
SQL> commit;
Commit complete.
SQL>
5:刪除臨時字段price_tmp
SQL> alter table test drop column price_tmp;
Table altered.
方案2:
另外一種方法就是備份數據,然后刪除全部數據,然后修改表結構,最后將數據更新回去。如下所示:
1:備份原表數據
SQL> create table test_bak
2 as
3 select * from test;
Table created.
SQL>
2:清理刪除原表數據
SQL> truncate table test;
Table truncated.
3:修改表資源的精度或標度
SQL> alter table test modify price number(38,3);
Table altered.
SQL>
4:將數據還原回去
SQL> insert into test
2 select * from test_bak;
4 rows created.
SQL> commit;
Commit complete.
SQL> select * from test;
PRODUCT_ID PRICE
---------- ----------
1001 18.2
1002 38.5
1003 34.8
1004 87.4
SQL>
另外,需要注意的是,這兩者方法都必須確保操作時,沒有業務或應用程序操作該表,否則會有數據一致性問題。