网站首页
JSP空间
动态资讯
开源项目
技术文档
资源下载
J2EE资源
客户论坛
在线支付
 
  技术文档>>数据库技术>>Oracle技术>>Oracle开发>查看文档  
  实例讲解如何更改字段至兼容的不同类型 (1)     
  文章作者:未知  文章来源:赛迪网技术社区  
  查看:85次  录入:管理员--2008-04-03  
 

【赛迪网-it技术报道】在实际的工作和学习中,我们可能由于疏忽将一个字段定义为varchar2类型,后来插入里面的数据又都是数字,在此之后,你会突然发现这个字段确实应该为number类型,而此时如果我们想在不影响用户使用的前提下,或者说尽量小的影响用户,保证数据不丢失的情况下,来更改这个数据类型,这个时候如果我们用普通的alter table modify命令,就可能要遇到错误了。示例如下:

22:25:31 sql> select * from t;

a

----------

10

22:25:32 sql> desc t

名称 是否为空? 类型

-------------------- --------- --------------------

a varchar2(10)

22:25:34 sql> alter table t modify(a number);

alter table t modify(a number)

*

第 1 行出现错误:

ora-01439: 要更改数据类型, 则要修改的列必须为空

其实,类似的现象确实很多,如本来应该为date类型,结果被定义成varchar2类型等等,主要就是那些兼容的数据类型之间的转换定义。当然,为什么一开始会犯这样的错误,那可能原因就有多方面了,如一开始需求就不对等等。

下面,以上面那个例子为基础,介绍两种处理这种问题的方法。

第一种方法,通过增加列来完成

22:25:44 sql> alter table t add (b number);

表已更改。

22:34:16 sql> update t set b = to_number(a)

已更新 1 行。

22:34:39 sql> update t set a = null;

已更新 1 行。

22:34:50 sql> commit;

提交完成。

22:34:52 sql> select * from t;

a b

---------- ----------

10

22:34:55 sql> alter table t modify a number

表已更改。

22:35:21 sql> update t set a=b;

已更新 1 行。

已用时间: 00: 00: 00.01

22:35:33 sql> commit;

提交完成。

22:35:52 sql> alter table t drop column b;

表已更改。

在这种方法中最后也可以先drop column a,然后rename column b to a,达到的效果是一样的。

第二种方法:通过新建表,在新表上更改字段,最后rename新表来完成

22:41:44 sql> create table t1 as select * from t where 1=2;

表已创建。

22:42:14 sql> alter table t1 modify (a number);

表已更改。

22:42:24 sql> insert into t1 select * from t;

已创建 1 行。

22:42:37 sql> commit;

提交完成。

22:42:40 sql> drop table t;

表已删除。

22:42:46 sql> rename t1 to t;

表已重命名。

22:43:00 sql> desc t;

名称 是否为空? 类型

-------------- --------- -------------

a number

我就知道这两种常见的方法,不知道还有没有什么其他的好方法。如果有,请分享。建议使用第一种。

约束和索引都被摧残了,可以做个实验证明一下。

先建立测试表并插入数据

15:28:45 sql> create table t (a varchar2(10) not null);

表已创建。

已用时间: 00: 00: 00.03

15:28:47 sql> insert into t values ('10');

已创建 1 行。

已用时间: 00: 00: 00.00

15:28:55 sql> commit;

提交完成。

已用时间: 00: 00: 00.00

然后增加一个列,并且把数据复制过去

15:29:08 sql> alter table t add (b number);

表已更改。

已用时间: 00: 00: 00.01

15:29:31 sql> update t set b=to_number(a);

已更新 1 行。

已用时间: 00: 00: 00.01

15:29:42 sql> commit;

提交完成。

已用时间: 00: 00: 00.00

15:29:45 sql> alter table t modify b not null;

表已更改。

已用时间: 00: 00: 00.10

在原来的列上建立索引和约束

15:29:59 sql> create index ind_t_a on t(a);

索引已创建。

已用时间: 00: 00: 00.15

15:31:01 sql> alter table t add constraint uk_t_a unique(a);

表已更改。

已用时间: 00: 00: 00.03

斗转星移:

15:31:20 sql> alter table t drop column a;

表已更改。

已用时间: 00: 00: 01.20

15:32:06 sql> alter table t rename column b to a;

表已更改。

已用时间: 00: 00: 00.03

查看索引是否还在?可以看到索引已经被损坏了:

15:33:17 sql> select index_name,status from user_indexes where table_name='t';

未选定行

已用时间: 00: 00: 00.12

15:34:20 sql> select index_name,status from user_indexes order by 1;

index_name status

------------------------------ --------

pk_dept valid

pk_emp valid

已用时间: 00: 00: 00.35

然后查看约束是否还在?可以看到它也被摧残了

15:38:07 sql> select constraint_name,constraint_type,invalid,table_name from user_constraints where table_name='t';

constraint_name constraint_type invalid table_name

------------------------------ -------------------- ------- -----------

sys_c005423 c t

已用时间: 00: 00: 00.03

15:38:24 sql> select constraint_name,constraint_type,invalid,table_name from user_constraints;

constraint_name constraint_type invalid table_name

------------------------------ -------------------- ------- ------------

bin$lnda2w97sk69tbau945o7w==$0 c bin$w9znsgtts9+fs/438tqkua==$0

bin$6jxde6kdtsum1gym3py1eg==$0 c bin$w9znsgtts9+fs/438tqkua==$0

sys_c005423 c t

fk_deptno r emp

pk_dept p dept

pk_emp p emp

已选择6行。

已用时间: 00: 00: 00.23

验证后,唯一约束已经不起作用了

15:38:31 sql> select * from t;

a

----------

10

已用时间: 00: 00: 00.03

15:39:26 sql> desc t;

名称 是否为空? 类型

--------------- --------- ---------------------------

a not null number

15:39:29 sql> insert into t values(10);

已创建 1 行。

已用时间: 00: 00: 00.01

15:39:38 sql> commit;

提交完成。

已用时间: 00: 00: 00.00

15:39:44 sql> select * from t;

a

----------

10

10

可能大家会问,为什么还有一个c约束呢?上面的查询显示它是not null约束:

15:51:06 sql> select table_name,constraint_name,column_name from user_cons_columns where table_name='t';

table_name constraint_name column_name

------------------------------ ------------------------------ -----------------

t sys_c005423 a

16:09:29 sql> select search_condition from user_constraints where table_name='t';

search_condition

--------------------------------------------------------------------------------

"a" is not null

 
 
上一篇: oracle用户密码含有特殊字符应当如何处理 (1)    下一篇: 在oracle 10g中如何解决ora-19815错误
  相关文档
Oracle巧取指定记录以及巧用外关联查询 07-07
细化解析:怎样恢复一个丢失的 数据文件 11-15
超大型oracle数据库应用系统的设计方法 (1) 05-04
oracle 10g schedule job的常用操作 05-13
细化解析:oracle数据库的空间使用和管理 11-15
轻松四步帮你解决不能一次创建多表问题 06-17
详细讲解有关"cbo"优化的三个疑难问题 02-03
讲解数据仓库实施过程所需要考虑的步骤 02-20
用events 跟踪解决不能创建物化试图一例 06-17
如何使用ref cursor处理oracle的结果集 03-26
查看前五个最占用cpu的oracle会话进程 02-01
经验谈之项目中的Oracle开发技巧 05-13
sql server 2008的新特性概述:集成服务 02-21
教你轻松掌握Oracle数据库中的物理结构 09-29
实例讲解如何重复利用这个外部表的表结构 05-07
statspack中的library hit是如何计算的 03-06
用三个方法设置oracle数据库穿越防火墙 04-17
将移动数据文件到其它目录下的实用方法 03-03
大型mis软件的开发必须重视数据库设计 05-04
Oracle中如何实现某一字段自动增加1 01-15
返回首页 | 关于我们 | J网章程 | JSP空间合租 | 客服中心 | 免责声明 | 常见问题 | 参观机房
本站主机空间代理至厦门市华众网络科技有限公司
《中华人民共和国增值电信业务经营许可证》
编号:闽B2-20050079
@2005-2008福建JSP技术网 版权所有 闽ICP备05000928号
厦门(总部):13616026886 福州:0591-87655121
邮箱:admin@fjjsp.com 站长QQ,点击这里给我发消息