幾天前有人問我設置了字段的默認值為什麼無效呢?查找了一些資料,做了一個總結:
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
-----------------------------------------------------------------------------------
0test
列A也被添加的默認值。
綜上所述,Oracle的默認值處理要當心,如果應用中使用的是ORM工具,則必須要考慮對於字段為Null的處理,必要時在ORM工具中將Null轉換為default或插入時去掉值為Null的字段。
可以將下面的系統屬性作為默認值:
SYSDATE:系統時間
SYS_CONTEXT:系統上下文
USER:當前數據庫用戶
USERENV:用戶環境變量,可以獲取一些IP地址、協議、終端的信息
需要注意,默認值不能使用LEVEL、PRIOR、ROWNUM,會報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不要求有含義,以及並發性較高的場景。