每日一題 OCP1z0 047 2013 08

2021-12-30 05:40:58 字數 3408 閱讀 2004

[每日一題]ocp1z0-047 :2013-08-03約束―――延遲約束

這題是考延遲約束的相關知識點。在表cust設了主鍵cust_id(唯一並且非空),在主鍵設延遲約束,所謂延遲約束就是在dml時資料庫不判斷資料是否滿足約束,在commit時來判斷,如果commit,做dml操作時(這道題是插入的資料如果不滿足約束條件那就會做rollback)

這道題中,第一行,第二行資料的cust_id都為1,重複了,在提交時肯定會報錯,結果會回滾。相當於第一行,第二行不會插入到表cust中。

第三行,第四行的cust_id分別為1和2,沒有重複,提交時插入成功,會永久儲存。

所以可以看出正確答案是:c

延遲或立即約束

立即約束就是在每個dml語句執行時,立即判斷使用者所作的修改是否違返了約束,如果違返了,立即回當前正在執行的dml語句。我們以前我遇到的約束,都是這樣的立即約束。

延遲約束在dml語句結束時,並不判斷是否違反約束,而是事務提交時再判斷。如果約束違反,整個事務被回退。

在建立約束時,有兩個選項可以設定約束的檢查方式:

initiallyimmediate       :最初為立即約束。

initially deferred :最初為延遲約束。

如果將約束定為initiallyimmediate,那麼約束仍是立即的,但我們可以使用命令設為延遲的。而約束如果被設為了initially deferred,約束建立好了,就是延遲的。

我們來試下:

[html]

gyj@ocm> drop table t8;

table dropped.

gyj@ocm> create table t8(id number(10) constraint t8_id_c check(id>=5)

2 initially deferred,namevarchar2(20));

gyj@ocm> insert into t8 values(1,'gyj');

1 row created.

可以正常插入。約束的檢查被推遲了  

gyj@ocm> commit;

commit

* error at line 1:

ora-02091: transaction rolled back

ora-02290: check constraint (gyj.t8_id_c)violated

可以看到,提交時檢查出來此事務違反了約束,整個事務被回滾,事務也結束了。注意立即約束中,只會回滾違反約束的當前語句,而不會回滾整個事務。

如果我把約束建立成initiallyimmediate,最初為立即。那麼約束此時還是立即。需要使用如下命令,才能把約束設定為延遲的。而且,最初為延遲的約束,也可以使用此命令,設成立即的。initiallyimmediate和initially deferred都是可延遲的約束,下面的這條命令,可以將可延遲的約束,設定為延遲或立即。命令語法如下:

set constraints 約束名|all immediate|deferred

比如我上面建立的,是最初為延遲,我們也驗證過了,現在已經是延遲檢查了,下面我把它改為立即的

gyj@ocm> set constraint t8_id_cimmediate;

constraint set.

t8_id_c已經被改為立即的了,再插入違反約束的行,馬上就會報出錯誤:

gyj@ocm> insert into t8values(1,'gyj');

insert into t8 values(1,'gyj')

*error at line 1:

ora-02290: check constraint(gyj.t8_id_c)violated

這個命令只影響當前會話,並且只在commit和rollback命令執行前有效。下面我來試一下,仍舊是在剛才的會話中,執行乙個commit或rollback:

gyj@ocm> rollback;

rollback complete.

執行commit或rollback那個命令都行,這兩個命令都代表乙個事務的結束,set constrain命令的作用,也就是維持到乙個事務的結束。現在t8_id_c約束又回到了最初的狀態,它最初是延遲檢查約束。下面我再插入乙個違反約束的行:

gyj@ocm> insert into t8 values(1,'gyj');

1 row created.

已經可以插入了,直到提交才報錯:

gyj@ocm> commit;

commit

*error at line 1:

ora-02091: transaction rolled back

ora-02290: check constraint(gyj.t8_id_c)violated

initiallyimmediate我就不再試驗了,除了它最初是立即外,它和initially deferred的控制操作是一樣的。如果在建立約束時,沒有加這兩個選項中的任乙個,約束就是不可延遲的,對於不可延遲的約束,使用set constraint命令會報出錯誤。

我先把t8表上的約束建立為不可延遲的:

gyj@ocm> drop table t8;

table dropped.

gyj@ocm> create table t8(idnumber(10)constraint t8_id_c check (id>=5),name varchar2(20));

table created.

現在我把t8_id_c約束設為可延遲:

gyj@ocm> set constraint t8_id_cdeferred;

setconstraint t8_id_c deferred

*error at line 1:

ora-02447: cannot defer a constraintthatis not deferrable

報出了錯誤,因為aa3_id_c是不可延遲約束。

setconstraint命令的作用,只對當前會話的當前事務有效,另有一條命令,它的作用可以對當前會話中的所有事務有效:

alter session setconstraint=immediate|deferred|default;

immediate是立即,deferred是延遲,default是恢復建立約束時所設定的值.

操作如下:

[html]

gyj@ocm> drop table t8;

table dropped.

gyj@ocm> create table t8(id number(10)constraint t8_id_c check (id>=5),name varchar2(20));

table created.

gyj@ocm> alter session set constraint=deferred;

session altered.

每日一題 1

題目詳情 peter喜歡玩數字遊戲,但數獨這樣的遊戲對他來說太簡單了,於是他準備玩乙個難的遊戲。遊戲規則是在乙個n n的 裡填數,規則 對於每個輸入的n,從左上角開始,總是以對角線為起點,先橫著填,再豎著填。這裡給了一些樣例,請在樣例中找到規律並把這個n n的 列印出來吧。輸入描述 多組測試資料 資...

每日一題 1

注 分數越高的選手,排名越靠前。示例 1 輸入 5,4,3,2,1 輸出 gold medal silver medal bronze medal 4 5 解釋 前三名運動員的成績為前三高的,因此將會分別被授予 金牌 銀牌 和 銅牌 gold medal silver medal and bronz...

MySQL每日一題(1)

表1 person 表1 person 列名 型別 personid int firstname varchar lastname varchar personid 是上表主鍵表2 address 列名 型別 addressid int personid int city varchar state...