a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 186|回复: 1

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

[复制链接]
发表于 2012-8-4 14:06:19 | 显示全部楼层 |阅读模式
 Oracle的外键用来限制子表中参考的字段的值,必须在主表中存在。而且在主表的记录发生变化导致外键参考唯一约束值发生了变化时,定义了一系列的动作。
* M* F! F/ E, K, ~+ S+ U+ q  前面几篇文章介绍了Oracle所支持的3种约束行为NO ACTION、DELETE SET NULL和DELETE CASCADE.至于SQL标准中定义的其他操作,Oracle只能通过触发器来实现,这里给出一个简单的UPDATE CASCADE操作的例子。( Z* u6 g' h/ w7 p- n# r5 X4 P
  SQL> DROP TABLE T_C;
4 i- i4 ?+ R$ f1 m+ t3 s. c1 a7 [  表已删除。/ N/ i0 I  r( X$ X% O9 [) \) \( y
  SQL> DROP TABLE T_P;
# ?* P; K7 O* N: i2 I- ?  表已删除。; y7 |  \, m1 r6 ^. `% A% V$ D
  SQL> CREATE TABLE T_P (ID NUMBER, NAME VARCHAR2(30));
1 ^- a5 j2 c0 F7 A. {. B3 m# z  表已创建。
# j0 R3 Z" M: Y: {/ _9 E1 a  SQL> ALTER TABLE T_P ADD PRIMARY KEY (ID);4 N- \$ X& x9 c6 X0 z) U
  表已更改。
# q9 e, J6 N: w, \" n  SQL> CREATE TABLE T_C (ID NUMBER, FID NUMBER, NAME VARCHAR2(30));
( R. R& Q% F! V8 S: o# v  }  表已创建。1 l, F  p* h; C/ `3 D% u
  SQL> ALTER TABLE T_C ADD CONSTRAINT FK_T_C; I- Q/ P5 M! l- r
  2 FOREIGN KEY (FID)
: b0 J! K) i7 s- d9 k  3 REFERENCES T_P (ID);% J. f2 Y  D( R$ j0 K) x- M* F
  表已更改。) |0 Z, z2 L- r& }8 o
  SQL> INSERT INTO T_P VALUES (1, ’A’);! Q; {2 m' f# G/ E
  已创建 1 行。: U0 L4 K% L  R2 z2 v4 ^5 M9 L& ]
  SQL> INSERT INTO T_P VALUES (2, ’B’);
% q+ h3 u$ g$ u: T3 z* S  已创建 1 行。# }/ Y( |. w2 ?# r: R$ W, {
  SQL> INSERT INTO T_C VALUES (1, 1, ’A’);
% _7 z  q2 [% e/ _4 x/ n  已创建 1 行。) m) P' r( x# ^7 M0 o
  SQL> COMMIT;& @: H* _5 {1 }; w9 H0 d4 i
  提交完成。
: F' o. ~. Q! Z# X  检查一下直接更新操作:2 j5 E4 l3 D7 }2 c0 k" E# ^$ O  [
  SQL> SELECT * FROM T_P;9 N) g" E) `: h( C" E
  ID NAME% f3 ^, A6 X0 p6 _2 u2 q6 G9 H- W' t
  ---------- ------------------------------/ j: e" S: d6 q$ Y
  1 A
9 k: T7 a1 T+ h9 h  2 B
# I' f' Q6 s7 X- k2 p) y  SQL> SELECT * FROM T_C;
: A+ d2 k! W# Z7 |: h/ e4 c7 G' b  ID FID NAME
. E/ _/ {  R: v6 Z$ }, j* _8 Q  ---------- ---------- ------------------------------
7 K. D, O0 _4 R# J  1 1 A& B/ V7 a" F/ w, y0 v
  SQL> UPDATE T_P SET ID = 3 WHERE ID = 1;
: E# a+ \* p+ \  UPDATE T_P SET ID = 3 WHERE ID = 1" C6 L" i* `  Y/ E4 w
  *第 1 行出现错误:! S1 P& R4 F8 i$ I1 a% U# s
  ORA-02292: 违反完整约束条件 (YANGTK.FK_T_C) - 已找到子记录日志
回复

使用道具 举报

 楼主| 发表于 2012-8-4 14:06:20 | 显示全部楼层

Oracle辅导:Oracle外键约束修改行为(四)

  下面构造一个触发器:! M" H1 Y  ~* \" a2 L0 r: D0 l# a
  SQL> CREATE OR REPLACE TRIGGER T_P_UPDATE_CASCADE
, }) k$ g  B2 Q4 \4 [  2 BEFORE UPDATE ON T_P1 p  d1 s: L7 S9 f: c
  3 FOR EACH ROW
7 T: F' I9 p0 W3 p+ |- i  4 DECLARE
3 f! a2 ]* L. E; I0 c7 P5 c  5 V_STR VARCHAR2(32767);
) C5 r9 b% J. ?) ~  6 BEGIN+ ?4 I' U+ q# z+ z+ O9 g9 y2 N
  7 IF NVL(:NEW.ID, -1) != NVL(:OLD.ID, -1) THEN
) A6 r4 c! P$ w9 Y  8 FOR I IN (SELECT OWNER, TABLE_NAME, CONSTRAINT_NAME 2 k/ f; A5 p3 ?* Y2 u5 f
  9 FROM ALL_CONSTRAINTS* B% ?- z# \) F. [0 t6 I
  10 WHERE CONSTRAINT_TYPE = ’R’
' p- ?( H+ J0 J- D$ \  11 AND R_OWNER = ’YANGTK’
" |7 z3 K- Y% W, S/ f8 x5 |* n- m  12 AND R_CONSTRAINT_NAME IN
& ^! q& j4 u' {" c0 W" i  13 (SELECT CONSTRAINT_NAME FROM USER_CONSTRAINTS WHERE TABLE_NAME = ’T_P’))$ s- r& o9 L) c6 i. F" T1 q
  14 LOOP& v& K1 \) o8 \2 H8 r9 j. e
  15 V_STR := ’UPDATE ’ || I.TABLE_NAME || ’ SET ’; 0 p% n& G2 w. @$ A
  16 FOR J IN (SELECT COLUMN_NAME FROM ALL_CONS_COLUMNS / K* L0 {8 T5 J7 r7 F
  17 WHERE OWNER = I.OWNER" c3 Y( U1 y3 ]# E) q
  18 AND TABLE_NAME = I.TABLE_NAME ; X+ d6 M4 L8 g+ ~3 d7 n
  19 AND CONSTRAINT_NAME = I.CONSTRAINT_NAME) ) X" o0 w2 u& l: e! k( V4 c
  20 LOOP
$ e8 ~8 ]6 j/ \; g7 W! Q  21 V_STR := V_STR || J.COLUMN_NAME || ’ = ’ || :NEW.ID
1 a' }: t' r/ u6 I3 t$ w! P  22 || ’ WHERE ’ || J.COLUMN_NAME || ’ = ’ || :OLD.ID;8 L0 Z; |" K# \2 Y( i
  23 END LOOP;
1 t. c! {1 s, E  24 EXECUTE IMMEDIATE V_STR;
( ~: E, E$ m+ |5 j7 Q  25 END LOOP;6 K$ d/ N. K9 K
  26 END IF;
. O# C( Q+ s! Y' L6 c# w5 N  27 END;
* ^% N8 Y/ S1 D, ?  28 /7 D  H; j( c  B0 S7 j. [+ f; I6 q
  触发器已创建
% V8 X2 ~& F2 _  ~5 ?  SQL> SELECT * FROM T_P;' r) K9 Z  N0 U6 k: F
  ID NAME
4 A9 A, k/ q5 q, I1 \7 F  ---------- ------------------------------1 s+ J' m7 ]4 j+ g$ c
  1 A
* P2 E" ~" U% L7 M1 b  2 B
6 s0 s: W+ O* t: _3 {  SQL> SELECT * FROM T_C;
' c7 h# r9 ^% ?  ID FID NAME
! N0 [% w5 \) O1 Y  ---------- ---------- ------------------------------
/ w8 _( |* Y9 ?5 M# f( h. G  1 1 A  U% k; m6 f4 y: D+ D/ K: Z4 P
  SQL> UPDATE T_P SET ID = 3 WHERE ID = 1;
( c) G1 X0 H% z" ^  已更新 1 行。
3 ^- y5 N+ g8 [* Q  SQL> SELECT * FROM T_P;: S0 M+ n# D0 B* p# G7 C
  ID NAME) S- R) U" r: t1 M# z2 J
  ---------- ------------------------------
) g* f7 T3 q6 u9 }  3 A
6 ~& U; P7 @: |% F6 u& S  2 B9 A' E2 ?6 S! p; E
  SQL> SELECT * FROM T_C;
$ I% i! P! \6 Q/ m+ z  ID FID NAME' H9 u' d5 W$ V
  ---------- ---------- ------------------------------
: X3 H" d6 Z8 K  1 3 A0 f1 I. q% t& f6 p. x3 U; }
  采用动态SQL的好处是,即使新增了新的外键表,触发器也不用重新编辑:8 F6 P# r+ W: Y. \& f5 }1 k
  SQL> CREATE TABLE T_C1 (ID NUMBER, FID NUMBER, CONSTRAINT FK_T_C1 ; c6 f' A' c0 {% G& p: B) ?2 s+ F8 |
  2 FOREIGN KEY (FID) REFERENCES T_P);3 {; q$ a: a) s& _2 `$ H
  表已创建。* h# v' ^9 ^# A4 p! g
  SQL> INSERT INTO T_C1 VALUES (1, 3);
6 A7 k+ _0 G* V( b3 u  已创建 1 行。
+ i$ p: \: }7 ?  m& x. M, Y- L  SQL> UPDATE T_P SET ID = 1 WHERE ID = 3;
. y1 s, ]* |9 a1 J0 D/ S* ]  已更新 1 行。) ^; h* B3 I, p4 b& S
  SQL> SELECT * FROM T_P;
6 h  o4 ?/ C1 z$ q9 G( D5 L  ]  ID NAME
1 T6 |+ Y- q' u) l2 t  ---------- ------------------------------. m1 b7 O- [1 R+ b; u0 x
  1 A
) {8 z9 {+ I( T9 A) h  2 B
+ q# t& {3 g0 N/ T* W) U  SQL> SELECT * FROM T_C;: l2 l& w4 W& g% @: o
  ID FID NAME% j- p0 f  D7 x
  ---------- ---------- ------------------------------
5 D. U7 `* C6 S( i  1 1 A
' L- k( @# l' i3 l+ x  SQL> SELECT * FROM T_C1;
+ P* `" }) r/ E, z  ID FID
& d) _, K# O; s' y  U+ v1 v  ---------- ----------/ C& M: Q8 T( p
  1 1
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-5 17:51 , Processed in 0.226138 second(s), 23 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

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