【问题标题】:ORA-01439: column to be modified must be empty to change datatypeORA-01439: 要修改的列必须为空才能更改数据类型
【发布时间】:2021-12-01 02:56:19
【问题描述】:

我正在使用 Oracle 12c,同时尝试将数据类型从 NUMBER(8,0) 更改为 VARCHAR2(10) 面临如下错误:

Error report -
SQL Error: ORA-01439: column to be modified must be empty to change datatype
01439. 00000 -  "column to be modified must be empty to change datatype"
*Cause:    
*Action:

注意:列删除和重新创建需要大量时间,因为它有 6 个月的数据。

有人可以建议将数据类型更改为varchar(10)的替代方法

【问题讨论】:

    标签: oracle oracle12c alter


    【解决方案1】:

    不知何故,你必须付出代价,因为没有免费的午餐。

    这里有几个例子;工资列为varchar2(10)的示例表:

    SQL> create table test as
      2  select ename, cast(sal as varchar2(10)) sal
      3  from emp
      4  where rownum <= 5;
    
    Table created.
    

    创建一个“副本”,将sal 列修改为number

    SQL> create table test_new as
      2  select ename, to_number(sal) sal
      3  from test;
    
    Table created.
    

    删除原始表格(我知道如果它被其他表格引用,您可能无法这样做):

    SQL> drop table test;
    
    Table dropped.
    

    将新表重命名为其原始名称:

    SQL> rename test_new to test;
    
    Table renamed.
    

    就是这样;结果:

    SQL> select * from test;
    
    ENAME             SAL
    ---------- ----------
    SMITH             800
    ALLEN            1600
    WARD             1250
    JONES            2975
    MARTIN           1250
    
    SQL> desc test;
     Name                                      Null?    Type
     ----------------------------------------- -------- ----------------------------
     ENAME                                              VARCHAR2(10)
     SAL                                                NUMBER
    
    SQL>
    

    另一种选择,如果您不能删除原始表:

    SQL> drop table test;
    
    Table dropped.
    
    SQL> create table test as
      2  select ename, cast(sal as varchar2(10)) sal
      3  from emp
      4  where rownum <= 5;
    
    Table created.
    
    SQL> desc test;
     Name                                      Null?    Type
     ----------------------------------------- -------- ----------------------------
     ENAME                                              VARCHAR2(10)
     SAL                                                VARCHAR2(10)
    

    修改它的数据类型是行不通的,因为它不是空的(你已经知道了):

    SQL> alter table test modify sal number;
    alter table test modify sal number
                            *
    ERROR at line 1:
    ORA-01439: column to be modified must be empty to change datatype
    

    所以:添加一个数据类型为number 的新列,并将“旧”工资值放入其中:

    SQL> alter table test add new_sal number;
    
    Table altered.
    
    SQL> update test set new_sal = to_number(sal);
    
    5 rows updated.
    

    现在,删除原始列:

    SQL> alter table test drop column sal;
    
    Table altered.
    

    将新添加的列重命名为其原始名称:

    SQL> alter table test rename column new_sal to sal;
    
    Table altered.
    

    结果:

    SQL> select * From test;
    
    ENAME             SAL
    ---------- ----------
    SMITH             800
    ALLEN            1600
    WARD             1250
    JONES            2975
    MARTIN           1250
    
    SQL> desc test;
     Name                                      Null?    Type
     ----------------------------------------- -------- ----------------------------
     ENAME                                              VARCHAR2(10)
     SAL                                                NUMBER
    
    SQL>
    

    或者:

    SQL> drop table test;
    
    Table dropped.
    
    SQL> create table test as
      2  select ename, cast(sal as varchar2(10)) sal
      3  from emp
      4  where rownum <= 5;
    
    Table created.
    

    添加一个数据类型为number 的新列,并将“旧”工资值放入其中:

    SQL> alter table test add new_sal number;
    
    Table altered.
    
    
    SQL> update test set new_sal = to_number(sal);
    
    5 rows updated.
    

    清除原始列的内容,以便您可以更改其数据类型(因为它现在将是):

    SQL> update test set sal = null;
    
    5 rows updated.
    
    SQL> alter table test modify sal number;
    
    Table altered.
    

    将值放回那里:

    SQL> update test set sal = new_sal;
    
    5 rows updated.
    

    删除新添加的列:

    SQL> alter table test drop column new_sal;
    
    Table altered.
    

    结果:

    SQL> select * From test;
    
    ENAME             SAL
    ---------- ----------
    SMITH             800
    ALLEN            1600
    WARD             1250
    JONES            2975
    MARTIN           1250
    
    SQL> desc test;
     Name                                      Null?    Type
     ----------------------------------------- -------- ----------------------------
     ENAME                                              VARCHAR2(10)
     SAL                                                NUMBER
    
    SQL>
    

    我不知道哪个选项更快。对于小桌子,这并不重要。您在该表中有多少行?您说的是“6 个月”,但这并没有真正的帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-14
      • 1970-01-01
      • 2012-03-19
      • 2017-05-24
      • 2013-08-19
      • 1970-01-01
      • 2011-05-17
      • 1970-01-01
      相关资源
      最近更新 更多