4.4.6 事务中对完整性约束的违反
4.4.6 事务中对完整性约束的违反
事务可能包括几个步骤,在某一步之后完整性约束也许会暂时被违反,但是后面的某一步也许就会消除这个违反。
例如,假设我们有一个主码为name
的person
关系,还有一个属性是ouse,
并且spouse
是在person
上的一个外码。也就是说,约束要求spouse
属性必须包含在person
表里出现的名字假设我们希望在上述关系中插入两个元组,一个是关于John
的,另一个是关于Mary
的,这两个元组的配偶属性分别设置为Mary
和John,
以此表示John
和Mary
彼此之间的婚姻关系。无论先插入哪个元组,插入第一个元组的时候都会违反外码约束。在插入第二个元组后,外码约束又会满足了。
1. 延迟约束检查到事务结束时
为了处理这样的情况,SQL
标准允许将initially deferred
子句加入到约束声明中;
这样完整性约束不是在事务的中间步骤上检查,而是在事务结束的时候检查。
一个约束可以被指定为可延迟的(deferrable
),这意味着默认情况下它会被立即检查,但是在需要的时候可以延迟检查。
对于声明为可延迟的约束,执行set constraints constrain-list deferred
语句作为事务的一部分,会导致对指定约束的检查被延迟到该事务结束时执行。
然而,读者应该注意的是默认的方式是立即检查约束,而且许多数据库实现不支持延迟约束检查。
2. 通过设置null来让事务不违反完整性约束
如果spouse
属性可以被赋为null
,我们可以用另一种方式来避开在上面例子中的问题:
在插入John
和Mary
元组时,我们设置其spouse
属性为null
,然后再更新它们的值。然而,这个技术需要更大的编程量,而且如果属性不能设为null
的话,此方法就不可行。