常見問題--表的約束initially immediate 理解
初始化立即執行--在每條語句執行結束時檢驗約束
初始化延遲執行--一直等到事務完成後(或者呼叫set constraint immediate語句時)才檢驗約束
來看下面的程式碼:
SQL> create table t
2 ( x int constraint
check_x check ( x > 0 )
deferrable
initially immediate,
3 y int constraint
check_y check ( y > 0 )
deferrable
initially deferred
4 )
5 /
Table created.
SQL> insert into t values ( 1,1 );
1 row created.
SQL> commit;
Commit complete.
所以,當兩個約束同時滿足時才能正確無誤地插入行。但是,如果我試圖插入違反CHECK_X約束(初始化立即執行的約束)的行,則系統會立即檢驗約束,並得到下面的結果:
SQL> insert into t values ( -1,1);
insert into t values ( -1,1)
*
ERROR at line 1:
ORA-02290: check constraint
(OPS$TKYTE.CHECK_X) violated
由於CHECK_X是可延遲但初始化為立即執行的約束,所以這一行立刻被拒絕了。而CHECK_Y則不同,它不僅是可延遲的,而且初始化為延遲執行,這就意味著直到我用COMMIT命令提交事務或將約束狀態設定為立即執行時才檢驗約束。
SQL> insert into t values ( 1,-1);
1 row created.
現在它是成功的(總之到目前為止是成功的)。我將約束檢驗延遲到了執行COMMIT的時候:
SQL> commit;
commit
*
ERROR at line 1:
ORA-02091: transaction rolled back
ORA-02290: check constraint
(OPS$TKYTE.CHECK_Y) violated
此時資料庫將事務回滾,因為違反約束導致了COMMIT語句的失敗。這些語句說明了初始化立即執行與初始化延遲執行約束之間的區別。initially(初始化)部分指定Oracle什麼時候會進行預設的約束檢驗--是在語句結束時[immediate(立即執行)],還是在事務結束時[deferred(延遲執行)]。我還要說明deferred(可延遲)子句有什麼用。我可以發出命令,讓所有可延遲的約束變為延遲執行的。注意,你也可以對一個約束使用該命令;你不必讓所有可延遲的約束都變為延遲執行的:
SQL> set constraints all deferred;
Constraint set.
SQL> insert into t values ( -1,1);
1 row created.
由於將初始化立即執行的約束設定為延遲執行的模式,這個語句似乎執行成功;但是,當我用COMMIT語句提交事務時,看一下會發生什麼:
SQL> commit;
commit
*
ERROR at line 1:
ORA-02091: transaction rolled back
ORA-02290: check constraint
(OPS$TKYTE.CHECK_X) violated
事務提交失敗並回滾,因為在COMMIT語句之後對約束進行了檢驗。相反,我可以將初始化為延遲執行的約束變為"立即"執行的約束:
SQL> set constraints all immediate;
Constraint set.
SQL> insert into t values ( 1,-1);
insert into t values ( 1,-1)
*
ERROR at line 1:
ORA-02290: check constraint
(OPS$TKYTE.CHECK_Y) violated
前面在我提交前能執行的語句現在立即出了問題。因為我手動修改了預設的約束模式。
延遲約束有哪些實際用處呢? 有很多。它主要用於物化檢視(快照)。這些檢視會使用延遲約束來進行檢視重新整理。在重新整理物化檢視的過程中,可能會破壞完整性,而且將不能逐句檢驗約束。但到執行COMMIT時,資料完整性就沒問題了,而且能滿足約束。沒有延遲約束,物化檢視的約束可能會使重新整理過程不能成功進行。
使用延遲約束的另一個普遍原因是,當預測是否需要更新父/子關係中的主鍵時,它有助於級聯更新。如果你將外來鍵設為可延遲、但初始化為立即執行,那麼你就可以將所有約束設定為可延遲。
將父鍵更新為一個新值--至此子關係的完整性約束不會被驗證。將子外來鍵更新為這個新值。 COMMIT--只要所有受更新影響的子記錄都指向現有的父記錄,這條命令就能成功執行。
轉:http://www.host01.com/article/database/00060004/0542413042257005.htm
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/15720542/viewspace-622173/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- initially immediate 與 initially deferred
- SQL教程——常見的約束型別SQL型別
- 泛型的約束理解泛型
- 線上重定義拷貝表結構的NOT NULL約束問題Null
- 無順序約束的字串匹配問題字串匹配
- 雲端計算面試常見問題,怎麼理解shell?面試
- 【Nginx】常見問題Nginx
- js常見問題JS
- CSS常見問題CSS
- Git 常見問題Git
- PHP 常見問題PHP
- swiper常見問題
- nginx 常見問題Nginx
- java 常見問題Java
- MyBatis常見問題MyBatis
- 前端常見問題前端
- Git常見問題Git
- SQLServer常見問題SQLServer
- css 常見問題CSS
- HTML常見問題HTML
- PyMongo 常見問題Go
- xhtml常見問題HTML
- UITableview 常見問題UIView
- mysql常見問題MySql
- MySQL 常見問題MySql
- BlockUI常見問題BloCUI
- Mysql:常見問題MySql
- PostgreSQL/LightDB分割槽表之常見問題SQL
- 常見的Java面試問題Java面試
- 業務分析中有關詞彙表的常見問題 - modernanalystNaN
- Oracle常見問題一千問Oracle
- 你知道是哪個是常見的約束中MySql不支援的嗎?MySql
- 約束和異常處理
- 差分約束的一些理解
- 常見問題--oracle10g修改表結構Oracle
- JasperReport報表生成工具的基本使用和常見問題
- 網易iTownSDK常見問題
- weex常見問題解析