a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 249|回复: 1

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

[复制链接]
发表于 2012-8-4 14:06:19 | 显示全部楼层 |阅读模式
Oracle的外键用来限制子表中参考的字段的值,必须在主表中存在。而且在主表的记录发生变化导致外键参考唯一约束值发生了变化时,定义了一系列的动作。# a: X7 q$ f$ o9 i1 R! P
  前面几篇文章介绍了Oracle所支持的3种约束行为NO ACTION、DELETE SET NULL和DELETE CASCADE.至于SQL标准中定义的其他操作,Oracle只能通过触发器来实现,这里给出一个简单的UPDATE SET NULL操作的例子。1 \. W) V7 |* b/ d6 |: G6 G
  SQL> DROP TABLE T_C;
# }! {! o+ K4 N! O  表已删除。
* d9 e4 \( Y& Y  SQL> DROP TABLE T_P;7 V  [" G! H% j% U& y
  表已删除。  g0 A# w( \5 n+ ~, v1 c1 i
  SQL> CREATE TABLE T_P (ID NUMBER, NAME VARCHAR2(30));
0 [8 }7 I$ k- I- W! Y7 V5 E. f& Z  表已创建。1 A. y$ R. ~2 m/ _' ]1 }
  SQL> ALTER TABLE T_P ADD PRIMARY KEY (ID);
: _7 I1 r& V- S' }) d  表已更改。
5 r- o1 X! {( h* D2 L( @  SQL> CREATE TABLE T_C (ID NUMBER, FID NUMBER, NAME VARCHAR2(30));' b$ F! N1 u; T
  表已创建。! F/ I. P0 B% a3 S9 {9 J
  SQL> ALTER TABLE T_C ADD CONSTRAINT FK_T_C
' u& D) B, S+ ~$ E& ^* `( ]* Y  2 FOREIGN KEY (FID)# C# S, L1 u0 L5 r0 S! L0 c
  3 REFERENCES T_P (ID);- O4 e+ k3 H9 \1 ?) R# n
  表已更改。& L) H0 _' g# P- I
  SQL> INSERT INTO T_P VALUES (1, ’A’);" e" [( T* b. f
  已创建 1 行。. |2 R) r+ z6 b! x, {" O
  SQL> INSERT INTO T_P VALUES (2, ’B’);
0 j+ l2 b% i$ g  已创建 1 行。
/ H" h8 v, W' s; [) @6 a7 N6 y( F; m  SQL> INSERT INTO T_C VALUES (1, 1, ’A’);
6 o7 F1 s# y$ f  已创建 1 行。% [0 x* M3 O. u* ]) W6 l! r
  SQL> COMMIT;* t9 K$ O! j: p! w" }* {& `
  提交完成。
/ a$ u+ w" `: g' L$ r  检查一下直接更新操作:
& w8 P& y: s  ~7 k# l9 u  SQL> SELECT * FROM T_P;
  q+ R* Q% `: o) D. ~  `4 u$ B  ID NAME1 ^3 n- n+ K" P# g
  ---------- ------------------------------
* f+ H+ J6 W$ S8 F% A; L  1 A
! B# v% O$ [: F, `& z& ?  2 B
  b7 _. R7 |: f, c( c6 ^  y* Y  SQL> SELECT * FROM T_C;6 f& m, O$ U5 E# }
  ID FID NAME9 A) \3 n7 n. k! K3 E. w$ z: r" c
  ---------- ---------- ------------------------------# l$ A/ z; C. _' E
  1 1 A
8 _; W- N4 L) J/ U4 {6 P7 a+ \  SQL> UPDATE T_P SET ID = 3 WHERE ID = 1;5 f! Z! n2 S, V
  UPDATE T_P SET ID = 3 WHERE ID = 1
回复

使用道具 举报

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

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

  *第 1 行出现错误:
5 \" h: V# I9 Q. e( a. K  ORA-02292: 违反完整约束条件 (YANGTK.FK_T_C) - 已找到子记录日志+ t) E+ c9 t. P6 v
  下面构造一个触发器:
1 M6 v' R' L$ K+ g% Z9 M/ ^  SQL> CREATE OR REPLACE TRIGGER T_P_UPDATE_SET_NULL
* H% x' ^. H. J) E8 K' |  2 BEFORE UPDATE ON T_P
1 p0 i2 v+ E  n6 k  3 FOR EACH ROW
1 ~& c! g9 X6 P; T9 ^! M1 r: y  4 DECLARE
1 l: i: e! i1 g  5 V_STR VARCHAR2(32767);
& i. J0 C8 F( \. e" T' T4 b" A  6 BEGIN
) l+ }0 z+ F+ G4 p  7 IF NVL(:NEW.ID, -1) != NVL(:OLD.ID, -1) THEN
/ p- p3 U  i# G0 s7 v: Q6 N2 C  8 FOR I IN (SELECT OWNER, TABLE_NAME, CONSTRAINT_NAME
* x; R4 K1 \/ F; F  9 FROM ALL_CONSTRAINTS, Z/ [* V! {9 W3 w% m
  10 WHERE CONSTRAINT_TYPE = ’R’7 K8 R$ b- m4 P4 a
  11 AND R_OWNER = ’YANGTK’! u8 n2 ^2 {& n; \( b
  12 AND R_CONSTRAINT_NAME IN ( _6 @+ V# c2 [1 u/ k
  13 (SELECT CONSTRAINT_NAME FROM USER_CONSTRAINTS WHERE TABLE_NAME = ’T_P’))
0 M$ b# k5 `7 S1 n5 L. G  14 LOOP3 H% G$ e" z% @1 U
  15 V_STR := ’UPDATE ’ || I.TABLE_NAME || ’ SET ’;
4 y# X3 V( E  c9 N! l  16 FOR J IN (SELECT COLUMN_NAME FROM ALL_CONS_COLUMNS
! F3 u; U% W/ E7 H8 ^  17 WHERE OWNER = I.OWNER' M: s% h8 r1 }% u% i' d7 R: c
  18 AND TABLE_NAME = I.TABLE_NAME
6 v! t" h* ~1 H4 |% T8 n  19 AND CONSTRAINT_NAME = I.CONSTRAINT_NAME)
6 O, T, C# V$ u  20 LOOP% [" M/ \  R5 ^
  21 V_STR := V_STR || J.COLUMN_NAME || ’ = NULL ’
; g3 ]0 F2 V6 \0 V  22 || ’WHERE ’ || J.COLUMN_NAME || ’ = ’ || :OLD.ID;
! T, V. y- t: q: C! A  23 END LOOP;* i* o+ V( j* X8 n5 ]
  24 EXECUTE IMMEDIATE V_STR;
& h% E" O3 I8 Y" ^$ {# D5 a8 ~4 }' ]0 E  25 END LOOP;3 o7 i+ O; J; h! x' ?; X. @( e) a0 G4 [
  26 END IF;7 L7 F. ?2 o2 d$ u+ d( h1 t
  27 END;
. `" L) E" B7 o' ]! s  28 /( m  u( [) Q) _. Z
  触发器已创建! A1 q' z9 K3 p2 d' J" @
  SQL> SELECT * FROM T_P;8 Z! N: m* `3 M5 V5 X
  ID NAME
, v8 b9 Y9 ?! g" ~  ---------- ------------------------------: k" R$ S3 T: `; z" w1 m2 n
  1 A
+ W) E& z  g. C, n7 i! I: r  2 B
9 I& @7 D! F& \' X' G, h  SQL> SELECT * FROM T_C;/ K) q* G0 s3 W
  ID FID NAME8 }8 |9 n* V& Z0 q' [
  ---------- ---------- ------------------------------
7 p9 X9 O9 \* @8 G" M  1 1 A, ~/ W3 A- ?" H2 v% b4 b
  SQL> UPDATE T_P SET ID = 3 WHERE ID = 1;( J/ R  N8 g) _( D
  已更新 1 行。" g/ X4 S! }8 g* F' j+ d1 ~* |
  SQL> SELECT * FROM T_P;
; J7 j. Q8 }# C  ID NAME9 y8 [4 |* T2 `7 q# L) Y2 D$ \
  ---------- ------------------------------
% s9 E# |# P; V4 r) \9 g  3 A+ e& a' |$ ]; q  S
  2 B0 L+ ^2 |) e7 ^* k& @& K
  SQL> SELECT * FROM T_C;
, }' t/ U7 P- a  ID FID NAME
  G2 f& x% s$ j8 K# b- p/ ^% Y  ---------- ---------- ------------------------------( X0 o# \/ i  o% h# s
  1 A/ j. l- R- u; \5 f5 I! r$ l; o
  UPDATE SET NULL操作其实和UPDATE CASCADE很相似,不同之处无非是一个置为NULL,另一个置为主键的新值。
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-9-28 08:14 , Processed in 0.197756 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

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