a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 143|回复: 1

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

[复制链接]
发表于 2012-8-4 14:06:19 | 显示全部楼层 |阅读模式
Oracle的外键用来限制子表中参考的字段的值,必须在主表中存在。而且在主表的记录发生变化导致外键参考唯一约束值发生了变化时,定义了一系列的动作。
. z1 m. C$ c5 b! Q  z; G  前面几篇文章介绍了Oracle所支持的3种约束行为NO ACTION、DELETE SET NULL和DELETE CASCADE.至于SQL标准中定义的其他操作,Oracle只能通过触发器来实现,这里给出一个简单的SET DEFAULT操作的例子。; ]) s4 z& \# R
  SQL> DROP TABLE T_C;
7 n$ @; s" P' A2 j0 ]  表已删除。
) J# _7 |1 @+ o3 k! k' n! T  SQL> DROP TABLE T_P;6 e. X6 j8 q! V9 i& X- C6 u" `
  表已删除。
5 z% v8 R, z. ?6 A7 E  SQL> CREATE TABLE T_P (ID NUMBER, NAME VARCHAR2(30));
, ~0 J! B2 ^% D: S  表已创建。$ N% a2 e4 A4 {2 V# p4 _. |1 G3 |
  SQL> ALTER TABLE T_P ADD PRIMARY KEY (ID);5 z/ Z& Q  ?8 E
  表已更改。& Z' ^: V0 m1 q+ j7 S
  SQL> CREATE TABLE T_C (ID NUMBER, FID NUMBER, NAME VARCHAR2(30));4 y0 g4 H3 @$ [) Z; G, x5 ?1 m0 P, ]$ N
  表已创建。7 B* A+ ~' B" ?% W7 J, l) T
  SQL> ALTER TABLE T_C ADD CONSTRAINT FK_T_C. ]" U  q. }: }) g/ R8 _
  2 FOREIGN KEY (FID)$ C/ [7 e9 ~" Q% O- N
  3 REFERENCES T_P (ID);) r7 r  _2 i0 P. U6 q8 s! z$ a; ~
  表已更改。$ K& V5 J7 a! F, T8 J
  SQL> INSERT INTO T_P VALUES (1, ’A’);  X: P1 ]0 W0 _2 t# r
  已创建 1 行。
% b; W7 Q' i* [# [+ D; x  SQL> INSERT INTO T_P VALUES (2, ’B’);
+ ?' J: Q% E$ P% H+ n) i  已创建 1 行。8 v+ D, [8 A, `4 N% B
  SQL> INSERT INTO T_C VALUES (1, 1, ’A’);
" S# t' _! I; u# \9 C  已创建 1 行。
& W5 j! I1 r; V& }$ L% e, B  SQL> COMMIT;
( V8 p6 `7 {& p0 J  提交完成。- j. l! v( B3 ^. `
  检查一下直接更新操作:
9 k0 u0 A, v& s3 v. k  SQL> SELECT * FROM T_P;( D9 k- l4 G( c$ d0 \$ C
  ID NAME
5 ?, f5 q9 q# t9 `0 l8 p- j$ R! `  ---------- ------------------------------
. @+ }: e# Q9 }- k2 `) n  1 A
4 k& z  |6 l9 R+ E* @  2 B
& o! @1 C' ^9 n% C4 G8 \! ?  A  SQL> SELECT * FROM T_C;- N; N: }5 R3 a
  ID FID NAME$ n. z9 ^; G! G
  ---------- ---------- ------------------------------! \/ n& b& ~6 U+ j' R
  1 1 A6 w" z8 K/ C4 y2 j% K) B
  SQL> UPDATE T_P SET ID = 3 WHERE ID = 1;+ Q! ?/ n  d$ K2 @
  UPDATE T_P SET ID = 3 WHERE ID = 1
回复

使用道具 举报

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

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

  *第 1 行出现错误:
# o2 f) R0 k6 d1 T  ORA-02292: 违反完整约束条件 (YANGTK.FK_T_C) - 已找到子记录日志4 Q' m) j0 R4 E
  下面构造一个触发器:
" L$ N; X9 {: v- y) t  r  SQL> CREATE OR REPLACE TRIGGER T_P_SET_DEFAULT
0 |/ s4 U6 D* N8 J' W' s3 J6 P  2 BEFORE DELETE OR UPDATE OF ID ON T_P
0 J4 L( J, Q) ]% k: Z0 f  3 FOR EACH ROW
& ^2 ?/ h# ?5 O& v" f5 `, R2 ]  4 WHEN (NVL(NEW.ID, -1) != NVL(OLD.ID, -1))& F0 P; u) T) I; L+ U
  5 DECLARE
0 ~7 R% z& b, z6 ^  6 V_STR VARCHAR2(32767);1 z% t4 |6 i! r
  7 BEGIN6 ?8 w2 g* U! H  X6 w
  8 FOR I IN (SELECT OWNER, TABLE_NAME, CONSTRAINT_NAME ( j7 W0 _" q- @8 i1 S/ V% r% q
  9 FROM ALL_CONSTRAINTS
5 s2 h: P& S. v* G. D* h  10 WHERE CONSTRAINT_TYPE = ’R’
. u& A. a2 _* W: |$ |  V5 l$ |" _- f  11 AND R_OWNER = ’YANGTK’
; E$ ^2 X* \6 i2 f) v( V+ R! {  12 AND R_CONSTRAINT_NAME IN
' i; Q# ^- m9 O: f  13 (SELECT CONSTRAINT_NAME FROM USER_CONSTRAINTS WHERE TABLE_NAME = ’T_P’))
+ q% r, v3 n) \7 G2 n3 [  14 LOOP
) a/ W: h6 B: m8 p  A& Q  15 V_STR := ’UPDATE ’ || I.TABLE_NAME || ’ SET ’; ) L, L/ Z" s, t& `# \2 t
  16 FOR J IN (SELECT A.COLUMN_NAME, B.DATA_DEFAULT) G, i/ t! B: S7 E
  17 FROM ALL_CONS_COLUMNS A, ALL_TAB_COLUMNS B( y3 j5 W; C! }1 G/ Q* B9 i- U4 j' \
  18 WHERE A.OWNER = I.OWNER
" q* G+ Y6 a4 m  19 AND B.OWNER = I.OWNER
; [+ V/ @8 l% Q+ w& m+ V  20 AND A.TABLE_NAME = I.TABLE_NAME/ y3 B+ n) l" \* P6 k0 b" g) R
  21 AND B.TABLE_NAME = I.TABLE_NAME
- m; p2 c' T) B+ @, d  22 AND A.COLUMN_NAME = B.COLUMN_NAME
& P7 }0 J/ ^- k6 ?% L, a6 r1 y  23 AND CONSTRAINT_NAME = I.CONSTRAINT_NAME)
2 }) @, ?1 T( X% _5 o. _! V) s" p5 M. W  24 LOOP6 [5 s% U+ P. v8 p8 q+ P
  25 V_STR := V_STR || J.COLUMN_NAME || ’ = ’ || J.DATA_DEFAULT * B' K" E! t- r3 g) y7 ]
  26 || ’ WHERE ’ || J.COLUMN_NAME || ’ = ’ || :OLD.ID;9 p: Y9 @  O4 I# y, h
  27 END LOOP;
% g0 s' `5 a$ [) |  28 EXECUTE IMMEDIATE V_STR;
% X; T# {" s% ]2 }" z: W* Z  29 END LOOP;- b0 N& X+ C; L3 b( {# D/ ^8 i
  30 END;
# R+ r4 Y, E2 m% q  31 /
; F5 \& b; w+ I) v# P& _  触发器已创建6 [- y" {  ~1 i
  SQL> ALTER TABLE T_C MODIFY FID DEFAULT 2;
  p0 G9 R0 e; V! l7 t1 `/ }  表已更改。
7 o2 a; [# T- R: b9 Z8 m  SQL> SELECT * FROM T_P;( P, [* F1 h+ ]* G# \8 t
  ID NAME
! i, ^  e0 J) f# \: P( k5 z1 k9 @( a  ---------- ------------------------------
. X0 b' @# E. D- f/ u  1 A4 i* I  H0 {' ]2 w4 v- r1 W3 U
  2 B
: @7 e. w. X5 N8 L- ~  SQL> SELECT * FROM T_C;3 e6 {% ~0 d* V8 D! ?1 h1 g
  ID FID NAME
; @  x& l% O0 F1 |1 A! ?" i* \  ---------- ---------- ------------------------------
& |1 T5 w6 I( {! b7 g  1 1 A( R2 v& N& `6 w$ {# B8 a9 K3 b
  SQL> UPDATE T_P SET ID = 3 WHERE ID = 1;  F6 H' @+ G5 B4 K5 j) V
  已更新 1 行。) p$ Y; |1 f% m2 c
  SQL> SELECT * FROM T_P;+ {% j" w  l" ~3 h( }
  ID NAME
- M/ N2 [) u. Q  ---------- ------------------------------( {* @5 e! \' e" ?
  3 A
& q9 O, G( P. V! f9 v  2 B
% }! X& R* V  z% d; S) x. \  SQL> SELECT * FROM T_C;( e% x9 V& x0 l, R6 m) H
  ID FID NAME3 N+ c) S7 N1 I2 J4 I5 x
  ---------- ---------- ------------------------------9 y6 ^8 P, ?/ X& J
  1 2 A
& e! b$ D2 X5 ?! Z* B9 `7 v  下面检查一下DELETE操作是否有效:
9 m# Z- r% v, P& r* V! y& @; ?6 H  SQL> UPDATE T_C SET FID = 3;7 B$ l; y+ [5 N* U- z0 ^
  已更新 1 行。! e! p% h* P( I2 {  }9 R9 m$ A! v
  SQL> SELECT * FROM T_C;
4 J5 N% K! d* ]5 B4 U! d  ID FID NAME5 t# K% n7 ?4 v' A0 |
  ---------- ---------- -----------------------------4 Y/ Y& F1 K# f% i' [
  1 3 A
3 S. W. a9 l- p& A3 z  SQL> DELETE T_P WHERE ID = 3;4 x% B4 O: A4 k7 ~3 e/ o" N, `2 L
  已删除 1 行。
! S) l0 v1 I8 {1 @+ R( k5 E! c  SQL> SELECT * FROM T_P;
) M9 f+ d9 y) V/ a# ?  ID NAME3 [8 g! B3 t' p$ @9 A
  ---------- ------------------------------% S4 u' J! b8 C! D
  2 B
( I. x3 H* A- r& r4 ]4 K! W' X  SQL> SELECT * FROM T_C;) m' Z* t5 M. x, S
  ID FID NAME  l$ ?) ~7 k; K& w
  ---------- ---------- -----------------------------
5 n9 @, l5 M: u, X$ Z  A6 U  1 2 A
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-5 19:26 , Processed in 0.184635 second(s), 23 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

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