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

Oracle
Oracle 9i轻松取得建表和索引的DDL语句
Oracle 8x监控sysdba角色用户登陆情况
PB7 连接 Oracle 的设置方法
Oracle数据库的备份及恢复策略研究
Oracle三种上载文件技术
Oracle建立二进制文件索引的方法
Oracle数据库及应用程序优化开发者网络Oracle
Oracle PL/SQL入门慨述
Oracle PL/SQL入门案例实践
基于Oracle的面向对象技术入门基础简析开发者网络Oracle
PL/SQL编程经验小结开发者网络Oracle
Oracle的数据字典技术简析
基于Oracle的高性能动态SQL程序开发
Oracle9i取得建表和索引的DDL语句
PL/SQL实现Oracle数据库任务调度
Oracle 9i 数据库异常关闭后的启动
Oracle与SQL Server在企业应用的比较
Oracle捕获问题SQL解决CPU过渡消耗
Oracle平台应用数据库系统的设计与开发
Oracle使用PL/SQL操作COM对象

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


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-08-14   浏览: 842 ::
收藏到网摘: 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项目,数据库的默认值这里,大家都应该没有问题了!