创建相关表,无数据。
conn aa/aa
create table aa(id number,name varchar2(10));
commit;
1、字段数据为空,不管改为什么字段类型及字段大小,可以直接执行
原name数据类型为varchar2(10),改为varchar2(100)及nvarchar2(10)均成功
alter table aa modify name varchar2(100); -success
alter table aa modify name nvarchar2(100); -success
2、字段数据非空,修改字段长度,或兼容类型,可以直接执行(字段长度不能小于实际数据占用最大长度)
表插入数据:
insert into aa values(1,'aa');
insert into aa values(2,'bb');
commit;
1)字段修改为不兼容数据类型
目前name数据类型为nvarchar2(10),且字段有数据,直接修改不兼容数据类型失败:
alter table aa modify name varchar2(10); -faulure,报如下错误:
ORA-01439: column to be modified must be empty to change datatype
2)字段修改为兼容数据类型
目前name数据类型为nvarchar2(10),且字段有数据,直接修改兼容数据类型成功
alter table aa modify name nchar(10); -success
3)字段扩大
目前name数据类型为nvarchar2(10),且字段有数据,修改字段长度:
alter table aa modify name nvarchar2(100); -success,字段长度扩大没问题
4)字段缩小
alter table aa modify name nvarchar2(2); -success,字段值最大2,字段长度缩小到2没问题
alter table aa modify name nvarchar2(1); -failure,字段值最大2,字段长度缩小到1失败,会报下面错误
ORA-01441: cannot decrease column length because some value is too big
方法一:
1)原字段改临时字段名
alter table aa rename column name to name_tmp;
commit;
1)创建新字段(目标类型)
alter table aa add name varchar2(10);
commit;
2)新字段值=临时字段值
update aa set name=trim(name_tmp);
commit;
3)删除临时字段
alter table aa drop column name_tmp;
commit;
这种方法优点是简单,缺点是会改变表数据存储结构,可能会存在行迁移/行链接、碎片等问题(这问题可以通过表迁移解决)。
方法二:
1)创建临时字段(原类型和目标类型均可)
alter table aa add name_tmp varchar2(10);
commit;
2)临时字段值=原字段值
update aa set name_tmp=trim(name);
commit;
3)原字段值内容清空
update aa set name=null;
4)原字段类型修改为目标字段类型
alter table aa modify name varchar2(10);
5)原字段什=临时字段值
update aa set name=trim(name_tmp);
commit;
6)删除临时字段
alter table aa drop column name_tmp;
commit;
方法二对表结构没有改变,但当表数据量大时,影响较大。
4、字段数据为空或非空,修改字段名称,不管数据类型,方法一种
alter table aa rename column name to column name_new;