转载请注明出处:http://blog.csdn.net/guoyjoe/article/details/9723007

[每日一题] OCP1z0-047 :2013-08-03  约束―――延迟约束....................................................23_延迟约束

[每日一题] OCP1z0-047 :2013-08-03  约束―――延迟约束....................................................23_约束_02


这题是考延迟约束的相关知识点。在表CUST设了主键cust_id(唯一并且非空),在主键设延迟约束,所谓延迟约束就是在dml时数据库不判断数据是否满足约束,在commit时来判断,如果commit,做dml操作时(这道题是插入的数据如果不满足约束条件那就会做rollback)

这道题中,第一行,第二行数据的cust_id都为1,重复了,在提交时肯定会报错,结果会回滚。相当于第一行,第二行不会插入到表CUST中。

第三行,第四行的cust_id分别为1和2,没有重复,提交时插入成功,会永久保存。

 

所以可以看出正确答案是:C

 

 

 

关于延迟约束的知识点,参考我的博客:

http://blog.csdn.net/guoyjoe/article/details/8640270

 

延迟或立即约束

立即约束就是在每个DML语句执行时,立即判断用户所作的修改是否违返了约束,如果违返了,立即回当前正在执行的DML语句。我们以前我遇到的约束,都是这样的立即约束。

  延迟约束在DML语句结束时,并不判断是否违反约束,而是事务提交时再判断。如果约束违反,整个事务被回退。

在创建约束时,有两个选项可以设置约束的检查方式:

Initiallyimmediate       :最初为立即约束。

Initially deferred :最初为延迟约束。

 如果将约束定为Initiallyimmediate,那么约束仍是立即的,但我们可以使用命令设为延迟的。而约束如果被设为了Initially deferred,约束建立好了,就是延迟的。

我们来试下:

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是恢复创建约束时所设置的值.

操作如下:


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. 


QQ:252803295

学习交流QQ群:
DSI&Core Search  Ⅰ 群:127149411(技术:已满)
DSI&Core Search  Ⅱ 群:177089463(技术:未满)
DSI&Core Search  Ⅲ 群:284596437(技术:未满)
DSI&Core Search  Ⅳ 群:192136702(技术:未满)
DSI&Core Search  Ⅴ 群:285030382(闲聊:未满)



MAIL:oracledba_cn@hotmail.com

BLOG: http://blog.csdn.net/guoyjoe

WEIBO:http://weibo.com/guoyJoe0218

ITPUB: http://www.itpub.net/space-uid-28460966.html

OCM:   http://education.oracle.com/education/otn/YGuo.HTM