當前位置:成語大全網 - 新華字典 - 在mysql怎麽寫not deferrable

在mysql怎麽寫not deferrable

在mysql怎麽寫not deferrable

Oracle約束constraint是我們經常使用的壹種數據庫規則對象。constraint在數據庫中的作用就是從靜態角度對數據完整性進行維護。我們經常使用的主鍵primary key和外鍵foreign key,本質上就是約束的壹種形式。

對Oracle的約束,我們有三個屬性可以進行設置,分別為deferrable、deferred和validated。針對不同的需求設計場景,采用不同類型的屬性,可以幫助我們實現不同的約束效果。下面我們分別來進行實驗。

1、 環境準備

首先我們還是準備數據實驗環境。

SQL> create table t (id number);

Table created

SQL> alter table T

2 add constraint c_t_id1

3 check (id>5);

Table altered

我們創建了數據表T,在列id上添加了約束c_t_id1。約束內容很簡單,就是要求id值保證是大於5。約束c_t_id1使用的是默認選項,數據字典中對該約束的表示如下:

SQL> select constraint_name, constraint_type ctype, SEARCH_CONDITION cond, STATUS, DEFERRABLE, DEFERRED, VALIDATED from dba_constraints where table_name='T' and wner='SYS';

CONSTRAINT_NAME CTYPE COND STATUS DEFERRABLE DEFERRED VALIDATED

-------------------- ----- ---------- -------- -------------- --------- -------------

C_T_ID1 C id>5 ENABLED NOT DEFERRABLE IMMEDIATE VALIDATED

註意,此時約束的三個屬性取值分別為:deferrable: not deferrable;deferred:immediate;validated:validated;

我們觀察壹下此時數據表的插入現象:

SQL> insert into t values (1); //插入非法的數據;

insert into t values (1)

ORA-02290: 違反檢查約束條件 (SYS.C_T_ID1) //立刻報錯,將數據剔除!

SQL> insert into t values (6);

1 row inserted

SQL> commit;

Commit complete

SQL> select * from t;

ID

----------

6

結論:在默認情況下,Oracle的約束是不允許延遲(not deferrable)、立即應用和驗證的(immediate、validated)。在數據變化的時候,立即進行約束驗證。

2、 deferrable:約束應用可以延遲

deferrable默認值為not deferrable,字面含義是不可延遲。那麽我們如果設置可以延遲,效果是什麽呢?

SQL> alter table T

2 drop constraint C_T_ID1;

Table altered

SQL> alter table T

2 add constraint C_T_ID1

3 check (id>5)

4 deferrable;

Table altered

此時,數據字典中的情況是如下:

SQL> select constraint_name, SEARCH_CONDITION cond, STATUS, DEFERRABLE, DEFERRED, VALIDATED from dba_constraints where table_name='T' and wner='SYS';

CONSTRAINT_NAME CTYPE STATUS DEFERRABLE DEFERRED VALIDATED

-------------------- ----- -------- -------------- --------- -------------

C_T_ID1 C ENABLED DEFERRABLE IMMEDIATE VALIDATED

與默認情況相比,deferrable屬性變化為了deferrable。我們觀察壹下現象:

SQL> insert into t values (3);

insert into t values (3)

ORA-02290: 違反檢查約束條件 (SYS.C_T_ID1)

在插入數據的時候,立即進行約束驗證。和默認情況下沒有差異。那麽怎麽處理呢?

//手工設置deferred屬性為deferred

SQL> set constraint c_t_id1 deferred;

Constraints set

SQL> insert into t values (3); //此時插入數據時候,並不進行驗證操作了。

1 row inserted

SQL> insert into t values (7);

1 row inserted

SQL> commit;

commit

ORA-02091: 事務處理已回退

ORA-02290: 違反檢查約束條件 (SYS.C_T_ID1) //直到進行commit的時候,才會應用約束;

那麽,如何設置回原有的屬性呢?

SQL> set constraint c_t_id1 immediate;

Constraints set

SQL> insert into t values (4); //又恢復插入立刻檢查約束的狀態了?

insert into t values (4)

ORA-02290: 違反檢查約束條件 (SYS.C_T_ID1)

結論:單獨deferrable的含義就是是否允許約束檢查延後進行。單獨設置deferrable為deferrable之後,約束檢查延後是不可以直接使用的,要配合deferred參數,如果該參數是immediate,那麽約束還是在DML的時候進行應用。如果deferred參數設置為deferred,約束就是在事務commit提交的時候應用,出現錯誤就連帶回滾rollback整個事務。

3、 deferred:是否進行延遲應用

從上面的實驗中,我們可以看出deferred屬性是配合deferrable屬性使用的。當deferrable設置為deferrable之後,可以通過set constraints進行deferred屬性的設置,來確定約束應用時點。

本部分確定deferred定義的方式和與deferrable屬性的關系。是可以在定義約束是使用initially關鍵字來確定約束的deferred屬性取值。

SQL> alter table T

2 add constraint C_T_ID1

3 check (id>5)

4 deferrable initially deferred;

Table altered