1. 程式人生 > >Oracle欄位的預設值無效的原因

Oracle欄位的預設值無效的原因

幾天前有人問我設定了欄位的預設值為什麼無效,查找了一些資料,總結如下:
create table TEST(IDVARCHAR2(64),AVARCHAR2(3)default'0',NAMEVARCHAR2(100));
SQL>insert into test(a,name) values(null,'test');
1 row inserted
SQL>select * from test;
A NAME

  test

在上面的例子中,雖然A列設定了預設值為0,但插入空仍然無效。其實對於預設值,Oracle支援兩種方式:Default關鍵字,不指定列
先看第一種方式,
SQL>insert into test(a,name)values(default,'test');

1 row inserted
SQL>select * from test;
A NAME
0 test

列A終於有了預設值0。

再看第二種方式,
SQL>insert into test2(name) values('test');
1 row inserted
SQL>select * from test2;
A NAME
0 test

列A也被新增的預設值。

Oracle的預設值處理要當心,如果應用中使用的是ORM工具,則必須要考慮對於欄位為Null的處理,必要時在ORM工具中將Null轉換為default或插入時去掉值為Null的欄位。
  可以將下面的系統屬性作為預設值:
  SYSDATE:系統時間

  SYS_CONTEXT:系統上下文
  USER:當前資料庫使用者
  USERENV:使用者環境變數,可以獲取一些IP地址、協議、終端的資訊
  需要注意,預設值不能使用LEVEL、PRIOR、ROWNUM,會報ORA-00976錯誤。
  應用中使用預設值的常見場景是主鍵或自增列。正如我們所知,Oracle並未提供自增型別,這就需要我們結合預設值進行二次開發,通過預設值實現系統應用的透明。這裡結合筆者的經驗,提供兩種方案:
  觸發器+序列
  因為Oracle不支援在default中使用序列,因此我們只能使用觸發器來實現。
create table TEST(IDVARCHAR2(64),AVARCHAR2(3)default'0',
NAMEVARCHAR2(100));
  create sequence seq_test;
  create orreplace trigger tri_test
  before insert on test for eachrow
  begin
  if:new.idisnullthen
  select seq_test.nextvalinto:new.idfromdual;
  endif;
  end;
  /
  這種方式適用於對於ID不要求連續性的場景。
  Sys_guid()。這個函式返回32位長的資料庫全域性唯一標識。我們可以使用這個函式作為預設值。
  alter table TESTmodifyIDdefaultsys_guid()
  SQL>insert into test2(name) values('張三');
  1 row inserted
  SQL>select * from test2;
  ID                                  ANAME
  7CDB1AF556F6474FABA74FA7A60F08220   張三
  這種方式適用於ID不要求有含義,以及併發性較高的場景。