a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 137|回复: 0

[考试辅导] Oracle辅导:Oracle外键约束修改行为(一)

[复制链接]
发表于 2012-8-4 14:06:19 | 显示全部楼层 |阅读模式
Oracle的外键用来限制子表中参考的字段的值,必须在主表中存在。而且在主表的记录发生变化导致外键参考唯一约束值发生了变化时,定义了一系列的动作。7 f/ \6 b7 H6 s9 b+ D
  在SQL92标准中定义了几种外键改变后,如何处理子表记录的动作,其中包括:
1 [3 i; Z, g. k$ \8 C  限制Restrict:这种方式不允许对被参考的记录的键值执行更新或删除的操作;置为空Set to null:当参考的数据被更新或者删除,那么所有参考它的外键值被置为空;% M: O# |, L) }% _7 d
  置为默认值Set to default:当参考的数据被更新或者删除,那么所有参考它的外键值被置为一个默认值;4 e4 t5 u% t) d( ]2 g, I
  级联Cascade:当参考的数据被更新,则参考它的值同样被更新,当参考的数据被删除,则参考它的子表记录也被删除;
, b( P4 q8 |/ F# J( u  不做操作No action:这种方式不允许更新或删除被参考的数据。和限制方式的区别在于,这种方式的检查发生在语句执行之后。Oracle默认才会的方式就是这种方式。
1 }6 a$ Z# K1 q8 y1 G- Q" c  A  Oracle明确支持的方式包括No action、Set to null和Cascade.对于Set to Default和Restrict,Oracle的约束类型并不直接支持,不过可以通过触发器来实现。
5 W: ~$ |! H6 a% O( }7 g& o5 a0 p  简单看一下Oracle的默认处理方式No action:* X) G9 S  Q  e. c  ^
  SQL> CREATE TABLE T_P (ID NUMBER, NAME VARCHAR2(30));1 U) d. |! K- q- W7 `/ V
  表已创建。2 m0 {$ p; d$ D. D3 H
  SQL> ALTER TABLE T_P ADD PRIMARY KEY (ID);; Z; o- P" S# D: }# m5 W
  表已更改。, B4 E9 _" _7 J+ D- h  t
  SQL> CREATE TABLE T_C (ID NUMBER, FID NUMBER, NAME VARCHAR2(30));
- J; x' H/ ~5 T  表已创建。$ ]0 L. ^+ V( s
  SQL> ALTER TABLE T_C ADD CONSTRAINT FK_T_C' X9 u6 q: j: B8 }9 s. y
  2 FOREIGN KEY (FID)
* B6 Y& D8 Q- K/ K  3 REFERENCES T_P (ID);$ G" F# k# s" f2 Q5 U
  表已更改。9 B2 a# h2 C+ c9 E9 p/ Q9 l
  SQL> INSERT INTO T_P VALUES (1, ’A’);+ x1 w) X1 O& H- r/ Q3 v) B5 v
  已创建 1 行。
, k( k0 L/ E: X$ U( e  SQL> INSERT INTO T_P VALUES (2, ’B’);
3 s) X6 J1 B  O% F( n  已创建 1 行。, a( S! r# d( g  @& j* E
  SQL> INSERT INTO T_C VALUES (1, 1, ’A’);
! c' k0 g# a2 N. A  已创建 1 行。; m8 C0 I/ {( l5 n- x, u' n3 L, \
  SQL> COMMIT;
) p" x* V2 {$ M9 n  提交完成。" q9 H; m3 o5 l9 _4 i
  对于No Action操作而言,如果主键的记录被外键所参考,那么主键记录是无法更新或删除的。
, u6 F) m" g" _! ~7 o  SQL> DELETE T_P WHERE ID = 1;
3 n. z! F* \: M1 F) t% w  DELETE T_P WHERE ID = 1
# E& C4 [4 B! i  *第 1 行出现错误:. Q) a; u' S3 W+ R) i! z- o
  ORA-02292: 违反完整约束条件 (YANGTK.FK_T_C) - 已找到子记录日志
8 Z, u2 {( ^% T  y# O  A  SQL> UPDATE T_P SET ID = 3 WHERE ID = 1;6 r' h3 E$ j* ]7 b) i, _6 M: U
  UPDATE T_P SET ID = 3 WHERE ID = 1! S, q* W; m- o0 B; Z8 V- X
  *第 1 行出现错误:1 o4 w. @% W9 \2 |2 N0 Q, @, k, @, y
  ORA-02292: 违反完整约束条件 (YANGTK.FK_T_C) - 已找到子记录日志
1 a! }5 z. ?! k1 l- r; u  SQL> DELETE T_P WHERE ID = 2;+ U' e" x6 A7 {
  已删除 1 行。
4 z' o: g9 p- a% p! w" o  不过No Action又和Restrict操作有所区别,No Action允许用户执行语句,在语句执行之后,或者事务结束的时候才会检查是否违反约束。而Restrict只有检测到有外键参考主表的记录,就不允许删除和更新的操作执行了。
3 b$ x2 H: o" D" c% D! }6 @7 R  这也使得No Action操作支持延迟约束:% u0 C2 W4 V/ K  Z' U3 ~
  SQL> ALTER TABLE T_C DROP CONSTRAINT FK_T_C;
/ \3 Z1 B* v: g0 `  表已更改。" {& b5 Z2 b; U: u
  SQL> ALTER TABLE T_C ADD CONSTRAINT FK_T_C
! @% O* L1 Q, a$ K' }# k5 e/ Z  2 FOREIGN KEY (FID)
1 u" Y9 i1 x8 g& Q  3 REFERENCES T_P (ID)
! m5 r4 W7 K5 l* Q2 W  4 DEFERRABLE INITIALLY DEFERRED;: m/ d/ ]+ u; t1 g. F1 ~  e
  表已更改。' k. p2 |6 a1 i( Q
  SQL> SELECT * FROM T_P;
; X) t! T1 H  q0 N; d" f  ID NAME
/ d& E6 }! P5 l, \; c( \/ |. k  ---------- ------------------------------! \$ {) C* a: v/ \+ m. V$ h! e0 R
  1 A
) O( X# G3 |# u' z0 f4 X; ~  SQL> SELECT * FROM T_C;$ X: w% O) e/ b8 r8 v- ]! K
  ID FID NAME
1 I% b9 b& u/ |; X: a  ---------- ---------- ------------------------------, e5 D7 ~/ W( }, o5 h2 V
  1 1 A
: }& ~% f7 Z5 V4 K  S7 }  SQL> DELETE T_P WHERE ID = 1;2 W3 d. J( _; ^( D
  已删除 1 行。* f7 u1 {; e; E
  SQL> INSERT INTO T_P VALUES (1, ’A’);
, l! t2 x4 B9 V  已创建 1 行。8 u: @4 c- v/ N# q$ Q( A# o/ E
  SQL> COMMIT;6 i8 T5 Y8 B( H& Z9 e8 P# v
  提交完成。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Woexam.Com ( 湘ICP备18023104号 )

GMT+8, 2024-9-28 08:17 , Processed in 0.559009 second(s), 22 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表