在创建约束的时候,有2种选项 deffered(延迟约束),not deffered(不延迟约束,立即检验,这是默认的选项)
例如:
create table A(a int constraint check_a check(a>0),b int check check_b(b>0));
create table A(a int constraint check_a check(a>0) not deferrable,b int constraint check_b check(b>0) not deferrable);
--以上2种定义出来的表都是没有延迟约束的,也就是说,这是我们平时经常创建的表
--我们往A表插入数据
正常插入
![](//img.blog.itpub.net/blog/attachment/201312/24/29227735_13878556331t1l.jpg?x-oss-process=style/bb)
不正常插入会立即报错
drop table A;
create table A(a int constraint check_a check(a>0) deferrable initially immediate,b int constraint check_b check(b>0) deferrable initially deferred);
对于有延迟约束的表,插入更新数据时,带有 deferrable initially immediate的选项时会立即检查约束,
带有deferrable initially deferred的选项时不会立即检查约束。
当使用commit提交事务时,这是会检查延迟约束,如果有违反约束的记录存在,则自动回滚事务
当使用 set contraint check_b immediate,也会检查延迟约束,但是不会自动回滚事务
延迟约束有什么用???
1.用于物化视图
用于每插入一条,或修改数据时并不立即检查约束,到提交事务时才检查约束。。。
2.用于更新级联
对于2个有主外键关系的表,更新时就有个麻烦
比如我有2张表,q1(教师id,姓名name ) q2(学生id,姓名,教师id ) 其中q2的教师id是一个外键
往q1,q2里插入一条数据
现在我想更改q1表中老师1的t_id号,但由于外键原因,由于在q2表中已经有了对该id的引用,所以 是改不了的
如果老师的id号确实写错了,但这2张表用了一段时间了,里面的数据比较多 ,该怎么办呢?
那么我们删除那个外键,重新建立一个延长约束外键
这样,我们先改q1表的教师id,然后再将q2表中对应的t_id 也改成一样,最后再提交时就不会违反外键的约束条件 了
例如:
create table A(a int constraint check_a check(a>0),b int check check_b(b>0));
create table A(a int constraint check_a check(a>0) not deferrable,b int constraint check_b check(b>0) not deferrable);
--以上2种定义出来的表都是没有延迟约束的,也就是说,这是我们平时经常创建的表
--我们往A表插入数据
正常插入
![](http://img.blog.itpub.net/blog/attachment/201312/24/29227735_13878556331t1l.jpg?x-oss-process=style/bb)
不正常插入会立即报错
![](http://img.blog.itpub.net/blog/attachment/201312/24/29227735_1387855676SAj8.jpg?x-oss-process=style/bb)
drop table A;
create table A(a int constraint check_a check(a>0) deferrable initially immediate,b int constraint check_b check(b>0) deferrable initially deferred);
![](http://img.blog.itpub.net/blog/attachment/201312/24/29227735_1387855741N1yo.jpg?x-oss-process=style/bb)
对于有延迟约束的表,插入更新数据时,带有 deferrable initially immediate的选项时会立即检查约束,
带有deferrable initially deferred的选项时不会立即检查约束。
![](http://img.blog.itpub.net/blog/attachment/201312/24/29227735_1387855929aNNj.jpg?x-oss-process=style/bb)
当使用commit提交事务时,这是会检查延迟约束,如果有违反约束的记录存在,则自动回滚事务
当使用 set contraint check_b immediate,也会检查延迟约束,但是不会自动回滚事务
![](http://img.blog.itpub.net/blog/attachment/201312/24/29227735_1387856041rr22.jpg?x-oss-process=style/bb)
延迟约束有什么用???
1.用于物化视图
用于每插入一条,或修改数据时并不立即检查约束,到提交事务时才检查约束。。。
2.用于更新级联
对于2个有主外键关系的表,更新时就有个麻烦
比如我有2张表,q1(教师id,姓名name ) q2(学生id,姓名,教师id ) 其中q2的教师id是一个外键
![](http://img.blog.itpub.net/blog/attachment/201312/24/29227735_1387856434XsFN.jpg?x-oss-process=style/bb)
往q1,q2里插入一条数据
![](http://img.blog.itpub.net/blog/attachment/201312/24/29227735_1387858708bpBj.jpg?x-oss-process=style/bb)
现在我想更改q1表中老师1的t_id号,但由于外键原因,由于在q2表中已经有了对该id的引用,所以 是改不了的
![](http://img.blog.itpub.net/blog/attachment/201312/24/29227735_1387858950QQ4M.jpg?x-oss-process=style/bb)
如果老师的id号确实写错了,但这2张表用了一段时间了,里面的数据比较多 ,该怎么办呢?
那么我们删除那个外键,重新建立一个延长约束外键
![](http://img.blog.itpub.net/blog/attachment/201312/24/29227735_1387859360IiXp.jpg?x-oss-process=style/bb)
![](http://img.blog.itpub.net/blog/attachment/201312/24/29227735_1387859373kWW1.jpg?x-oss-process=style/bb)
这样,我们先改q1表的教师id,然后再将q2表中对应的t_id 也改成一样,最后再提交时就不会违反外键的约束条件 了
![](http://img.blog.itpub.net/blog/attachment/201312/24/29227735_1387859584hrRW.jpg?x-oss-process=style/bb)
![](http://img.blog.itpub.net/blog/attachment/201312/24/29227735_1387859612II84.jpg?x-oss-process=style/bb)
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/29227735/viewspace-1064119/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/29227735/viewspace-1064119/