日期:2014-05-16  浏览次数:20472 次

数据库中三大问题:约束、CASE语句和文件(转)

本文用实例方式讲述了关于约束、CASE语句和文件三大问题。

约束

“定义为可延迟(deferrable)”的约束能指定为:

?

1. initially immediate(初始化即时执行)或

2. initially deferred(初始化延迟执行)。

?

知道什么是延迟约束,但不明白什么叫“初始化即时执行的可延迟约束”和“初始化延迟执行的可延迟约束”。请解释二者的差别。更有,这些约束有什么用途?这是通常容易混淆的问题。我希望下面的例子能解释清晰。初始化即时执行/延迟执行规定了在默认情况下应该怎么执行约束:

?

初始化即时执行:在每条语句执行结束时检验约束。

?

初始化延迟执行:直等到事务完成后(或调用set constraint immediate语句时)才检验约束。

?

通过代码分析两者不同:

?

SQL> create table t
            2 ( x int constraint
            check_x check ( x > 0 )
            deferrable
            initially immediate,
            3y 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(可延迟)子句有什么用。我能发出命令,让所有可延迟的约束变为延迟执行的。注意,