当前位置: 首页 > 图文教程 > 数据库 > Oracle > Oracle:为什么Oracle字段的默认值不能用?

Oracle
Oracle数据库技术(32)
Oracle数据库技术(33)
Oracle数据库技术(34)
Oracle数据库技术(35)
Oracle数据库技术(36)
Oracle数据安全面面观
Oracle数据操作和控制语言详解
Oracle数据库数据对象分析
解析Oracle 8i/9i的计划稳定性
使用Oracle实现实时通信
Oracle数据库中索引的维护
Oracle数据库游标使用大全
Oracle9i中监视索引的使用
在Oracle9i中使用多种Block Size
监控Oracle数据库的常用shell脚本
Performance Improvement Tips for Oracle on UNIX
Raw Partitions and Windows NT
How to use OS commands to diagnose Database Performance issues?
Raw Devices and Oracle - 20 Common Questions and Answers
Monitor Oracle Resource Consumption in UNIX

Oracle:为什么Oracle字段的默认值不能用?


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-08-14   浏览: 844 ::
收藏到网摘: n/a

以前做项目的时候,往往默认值都不管用!设置默认约束也不行吗?记得用java的hibernate来操作数据库,可是还是不行,查找了一些资料,做了一个总结:

 

  createtableTEST

  (

  IDVARCHAR2(64),

  AVARCHAR2(3)default'0',

  NAMEVARCHAR2(100)

  );

  SQL>insertintotest(a,name)values(null,'test');

  1rowinserted

  SQL>select*fromtest;

  ANAME

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

  test

 

  在上面的例子中,虽然A列设置了默认值为0,但插入空仍然无效。

 

  其实对于默认值,Oracle支持两种方式:

 

  Default关键字

 

  不指定列

 

  先看第一种方式,

 

 

  SQL>insertintotest(a,name)values(default,'test');

  1rowinserted

  SQL>select*fromtest;

  ANAME

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

  0test

 

  列A终于有了默认值0

 

  再看第二种方式,

 

 

  SQL>insertintotest2(name)values('test');

  1rowinserted

  SQL>select*fromtest2;

  ANAME

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

  0testA也被添加的默认值。

 

  综上所述,Oracle的默认值处理要当心,如果应用中使用的是ORM工具,则必须要考虑对于字段为Null的处理,必要时在ORM工具中将Null转换为default或插入时去掉值为Null的字段。

 

  可以将下面的系统属性作为默认值:

 

  SYSDATE:系统时间

 

  SYS_CONTEXT:系统上下文

 

  USER:当前数据库用户

 

  USERENV:用户环境变量,可以获取一些IP地址、协议、终端的信息

 

  需要注意,默认值不能使用LEVELPRIORROWNUM,会报ORA-00976错误。

 

  应用中使用默认值的常见场景是主键或自增列。正如我们所知,Oracle并未提供自增类型,这就需要我们结合默认值进行二次开发,通过默认值实现系统应用的透明。这里结合笔者的经验,提供两种方案:

 

  触发器+序列

 

  因为Oracle不支持在default中使用序列,因此我们只能使用触发器来实现。

 

 

  createtableTEST

  (

  IDVARCHAR2(64),

  AVARCHAR2(3)default'0',

  NAMEVARCHAR2(100)

  );

  createsequenceseq_test;

  createorreplacetriggertri_test

  beforeinsertontestforeachrow

  begin

  if:new.idisnullthen

  selectseq_test.nextvalinto:new.idfromdual;

  endif;

  end;

  /

 

  这种方式适用于对于ID不要求连续性的场景。

 

  Sys_guid()。这个函数返回32位长的数据库全局唯一标识。我们可以使用这个函数作为默认值。

 

 

  altertableTESTmodifyIDdefaultsys_guid()

  SQL>insertintotest2(name)values('张三');

  1rowinserted

  SQL>select*fromtest2;

  IDANAME

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

  7CDB1AF556F6474FABA74FA7A60F08220张三

 

  这种方式适用于ID不要求有含义,以及并发性较高的场景。相信以后的java项目,数据库的默认值这里,大家都应该没有问题了!