回答

收藏

光标在触发器中

技术问答 技术问答 99 人阅读 | 0 人回复 | 2023-09-12

我有一个现有的TABLE postn_matrix,其中包含员工列表和他们的响应数量。组织中的职位。* x$ w* a' Q0 q, t+ ?" R/ v
每当添加或删除用户的职位时,相应的计数就会通过此触发器反映在表格中(VIA UPDATE)8 p% u" i/ W3 U4 {* k2 m* J
现在,如果有一个新用户,他将不会在中输入任何内容postn_matrix,因此我必须为他/她插入一条新记录(VIA INSERT)。这需要从BASE
+ h* M: P" Q3 k, e+ Y3 b- P: a5 b8 Q6 gTABLE中引入。$ b1 h2 J$ r& d( a' J) M) F' z6 G
更新似乎工作正常,但我无法将新用户加入表格。3 b# y. r4 o4 e' p3 G
我一直在尝试使用游标处理这种情况。但这还没有任何帮助。我希望一些专家可以向我展示光.. 。除了使用光标以外的任何其他建议将不胜感激
+ K' O& U, Q8 M9 i( G$ h; tCREATE OR REPLACE TRIGGER TRIG1
4 b/ H& o6 ^! }; w8 n# g' qBEFORE INSERT OR DELETE ON (BASETABLE)! |& m6 ]. e. ~1 ~, }5 a3 {; ]0 O
FOR EACH ROW
  k) k4 y; P6 {: sDECLARE
; f/ N7 y' u: g* ]" I  cursor c1 is
: N1 Y, |8 d5 l7 {  select person_id
/ P" L# D/ H1 I1 W' f' ?) f  from postn_matrix;
, _& x! e+ I/ L4 x0 s; s& W# z4 H  v_temp varchar2(15);1 H$ V" U4 q3 C! \. F
BEGIN7 X2 P. o9 f& r0 |' w0 ]
  IF INSERTING THEN+ P+ q8 \4 f& A) R& z  B
    open c1;    2 Z, B# s- D9 F8 k3 C; `  f
    LOOP
# M( ?7 K; E5 X      fetch c1 into v_temp;
* ^6 C, c# A  g8 k      if v_temp!=:new.person_id THEN# h+ W0 \9 d/ @  M: q
        insert into POSTN_MATRIX (PERSON_ID)
( ]( ?  X4 [% a! s; O4 b        VALUES (:new.PERSON_ID);
! k3 g9 D1 b% Z  j% T9 t& Q6 w      else  C& \  b7 e9 I# G
        UPDATE POSTN_MATRIX
0 J+ o* k; S$ c$ ]) b1 c+ I' C        //this is working fine ;
; B1 v! w4 Y) W- q' ?3 o9 F      END IF;- i. j$ y) v- U3 P
    end loop;
' ~  T+ D' a+ o    close c1;1 u8 F2 c% [) h6 H( @
END* m8 U& C6 M, z# u: p: \* f
/
% T7 L# E' O3 [* F5 l" O* S  Y                ' i0 b4 X; K% _( E
解决方案:0 l8 b# l* `6 c; v
                . R* d9 F2 F7 k! q& R

7 v( P) ]5 t3 \8 t1 z& \
6 s1 f1 {  w/ @5 b5 R                因为循环的(这是缺少退出条款-希望你刚刚失去了这个翻译成问题),你会尝试插入记录pstn_matrix的 每一个  M1 ?+ v7 H7 J* E
记录光标回报,是否有任何匹配:new.person_id或不;
3 n. m8 e- b. i如果匹配的话,你也会做update。这可能不是您想要的,并且您可能会遇到违反约束的情况。您也没有设置计数器字段-; E' |1 G0 Z1 J2 \. L
如果该字段不能为空,则将出错。但是您没有说出您正在得到什么错误,如果有的话。  X: b9 ]* x: f* h" D$ p4 r$ p
如果必须通过触发器来执行此操作,则可以检查是否有新人要排:7 v4 P: z4 j( R
DECLARE1 _' N, U( I8 o/ V- F& `
  v_temp postn_matrix.person_id%TYPE;/ e; S9 l4 W" X1 b
BEGIN
- d# c# E' u  o3 y* |5 i  IF INSERTING THEN
( W+ h7 z4 K. X; \" A/ M8 a& }7 c    select max(person_id) into v_temp4 R4 v; [% C+ k0 d
    from postn_matrix! R! d" Z1 `; Y9 P- Y. c
    where person_id = :new.person_id;, g6 k8 c' q1 ]/ ?
    if v_temp is null then) {& P5 J; t7 P9 j( {! {1 I
      -- no record found, so insert one: ^# P0 t# K! L/ Z# V7 l1 ^( o
      insert into postn_matrix (person_id, position_count)! f2 K. f- _0 d- b
      values (:new.person_id, 1);2 m# `& [. W9 H0 U) X( A9 A4 A  d
    else
7 j) J" b8 u' o6 T9 F      -- record exists, so update
  ]2 K  T8 r$ _; d( {+ G      update postn_matrix ...: i, M; k$ \, m+ S
    end if;
! o. I: p/ r3 {" j  ...
( w( V$ r- S3 p# ^/ V…或使用merge。
. V# `2 e. g* l但是我不喜欢这种模型,您正在通过同时修改基表来设置数据差异的可能性。试图保持这种计数不一定像看起来那样简单。3 L0 ^4 X6 ^2 y) K- z' _* u, h
我通常希望将其设为一个视图,该视图将始终是最新的,并且不需要触发器来使事情变得复杂:3 u" h4 k. v7 P
create view postn_matrix as
2 \6 Y+ d, V  E/ H- v  select person_id, count(*)7 ^1 p% t4 t5 {1 D; Z: J8 c+ p
  from basetable
) b! F5 X4 ^( C4 R' d8 K. F% p  group by person_id;
' K3 y- B- f5 v, p7 _2 S! X当然,我可能会误解或简化了基表的功能以及所需的postn_matrix功能。拥有一个视图似乎有些琐碎。例如,如果您有单独的表person和person_position表,则可以添加外部联接以查看没有职位的人:3 J8 i- m$ ~  n
create view postn_matrix as9 H7 i# n1 {. d8 [0 E
  select p.person_id, count(pp.position_id), A# h; i% P' O) [: W, I& e
  from person p
& D& l1 B/ r5 `" n( w  left join person_position pp on pp.person_id = p.person_id7 t# b; Q6 w. x0 |( k- d
  group by p.person_id;
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则