回答

收藏

光标在触发器中

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

我有一个现有的TABLE postn_matrix,其中包含员工列表和他们的响应数量。组织中的职位。, T/ |% K5 `  @; C. p3 ^& {
每当添加或删除用户的职位时,相应的计数就会通过此触发器反映在表格中(VIA UPDATE)
1 ]/ f7 v, l' h: T! V) w$ ?5 y现在,如果有一个新用户,他将不会在中输入任何内容postn_matrix,因此我必须为他/她插入一条新记录(VIA INSERT)。这需要从BASE
0 f$ t) o5 l4 F2 x( h  wTABLE中引入。
* k3 o1 h  a; W3 U更新似乎工作正常,但我无法将新用户加入表格。
( |1 S( B7 c& k( a我一直在尝试使用游标处理这种情况。但这还没有任何帮助。我希望一些专家可以向我展示光.. 。除了使用光标以外的任何其他建议将不胜感激' A) r5 `( X  {  ^
CREATE OR REPLACE TRIGGER TRIG10 L# @! U/ Q) v1 ~3 h
BEFORE INSERT OR DELETE ON (BASETABLE)8 F5 M5 O0 a# W1 n' [9 E
FOR EACH ROW$ e2 J) R; r3 B
DECLARE  T; r) b- T8 y, X  {" m
  cursor c1 is
0 B6 A. F; K- p2 W2 M; }  select person_id
/ w8 x5 K+ z( o  from postn_matrix;
* \! ^* d9 C$ a1 W! X  v_temp varchar2(15);5 ^: n2 K8 {/ K: e
BEGIN
7 S9 L7 `2 W. I  IF INSERTING THEN& ]& ]1 [) }7 ?& ~" }+ p, i+ T
    open c1;   
) u0 d1 K$ d0 ]2 d3 t    LOOP9 d1 \( y/ _, y( n) ^0 ~3 a$ L& Q% h
      fetch c1 into v_temp;
9 Y. X" J+ E; }. X5 T! G      if v_temp!=:new.person_id THEN( k6 S% H5 R+ t% y3 A: ^( P9 k0 z
        insert into POSTN_MATRIX (PERSON_ID)
  {- j# ]6 D1 m: i6 e        VALUES (:new.PERSON_ID);$ e$ z& d2 Z5 ?- i
      else5 z. ~' m  B$ T$ O7 f9 k( D1 b6 _5 ^
        UPDATE POSTN_MATRIX
- q! j( B. u% R        //this is working fine ;1 u9 ~8 I% m$ b0 l/ B) |& |
      END IF;; }1 u& I% j% w# x1 H5 K
    end loop;
0 S' O- T  U/ j/ b7 L    close c1;
! D/ Z% a+ }% S* `4 o1 FEND( s; B; n5 x; g6 N' `
/4 k% D1 w1 y/ S0 p8 K  R
                7 T, h2 k/ g; V. a
解决方案:
3 Z  Z' m# ?. @% D; O                ' q0 V5 Y1 R3 y* J" b

/ f& G! S. _& Z' k0 c
% e9 g$ ?; ~% W4 G. c- |; J: l                因为循环的(这是缺少退出条款-希望你刚刚失去了这个翻译成问题),你会尝试插入记录pstn_matrix的 每一个
$ ]0 i% y" ~6 k+ _# m+ |4 ^记录光标回报,是否有任何匹配:new.person_id或不;  |' Q; ~+ [" ]" u, V
如果匹配的话,你也会做update。这可能不是您想要的,并且您可能会遇到违反约束的情况。您也没有设置计数器字段-$ f( R* x' g! D* |$ x7 g0 `" V  t4 c
如果该字段不能为空,则将出错。但是您没有说出您正在得到什么错误,如果有的话。
8 p2 W; |4 O3 ~+ t+ d如果必须通过触发器来执行此操作,则可以检查是否有新人要排:
$ k7 W  P! a' p8 CDECLARE
  X1 z! I" o% F4 b7 S; I  v_temp postn_matrix.person_id%TYPE;3 G# {1 M: R: l. }, K& ?
BEGIN
2 x( ]0 |: I# {0 Z) a8 D  IF INSERTING THEN) T/ ^7 E  X$ u! G
    select max(person_id) into v_temp3 w! |) _5 Y& ~0 }; Y7 o
    from postn_matrix  y( }* e2 y& ~4 z
    where person_id = :new.person_id;7 r! `" D8 o5 R: `
    if v_temp is null then. H1 D% e& ~2 Z8 L* U/ [
      -- no record found, so insert one! R; P7 d; t' |
      insert into postn_matrix (person_id, position_count)4 d- G+ N( T% M
      values (:new.person_id, 1);
) [4 H" @8 @+ X( x9 R" l    else4 a* U2 O  ^5 J( C: e0 d
      -- record exists, so update0 [3 p$ k; L8 D3 h, u2 J5 s
      update postn_matrix ...
/ U  l5 v; N% p' J0 a( M    end if;
" m& e4 ?4 @0 F  ~6 n. x  A, m  ...
$ [" `3 v5 T, ]& V& K( x& Y9 Y…或使用merge。  S. W- z; p) m
但是我不喜欢这种模型,您正在通过同时修改基表来设置数据差异的可能性。试图保持这种计数不一定像看起来那样简单。
: i0 d) O, v2 c: _; ]我通常希望将其设为一个视图,该视图将始终是最新的,并且不需要触发器来使事情变得复杂:) g: c" ^3 W! Q$ a( c
create view postn_matrix as
' d# a2 h4 X) F2 X. c" f* t  select person_id, count(*)- t# ^8 d% v+ x  _* c" w
  from basetable" i3 J- w- _  ^6 d. W& M* h' u/ @# s
  group by person_id;
6 m& E% d* `4 V; |; c; y当然,我可能会误解或简化了基表的功能以及所需的postn_matrix功能。拥有一个视图似乎有些琐碎。例如,如果您有单独的表person和person_position表,则可以添加外部联接以查看没有职位的人:
' M. @7 S. P, J" w: D6 `" lcreate view postn_matrix as# A4 J) l9 U* Y
  select p.person_id, count(pp.position_id)
0 \# ~9 B0 M, i. G% I' B  from person p
7 ~. }1 c, d- v' R5 _  left join person_position pp on pp.person_id = p.person_id0 }, _8 I) O- M
  group by p.person_id;
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则