“如何在oracle pl / sql中修复触发器?

didi8791

问题:需要对表A进行以下操作的触发器:每次在表A的TRT_PROCEDURE列的值中插入INSERT时,将1添加到表B的“ TRT_INS_COUNT”列。如果TRT_PROCEDURE值在表B中不存在表B,在表B中添加一行,以将TRT_INS_COUNT设置为1。

每次在表A上执行DELETE时,如果该过程值在表B中存在,则在该表B的TRT_DEL_COUNT列中添加1。如果在表B中不存在该过程值,则在该表B的行B中添加一行程序并将TRT_DEL_COUNT设置为1。

每次对表A中的列TRT_PROCEDURE进行UPDATE时,将1添加到表B中的列TRT_UPD_COUNT中。如果它不在表B中,则在表B中添加一行以获取过程值,并将TRT_UPD_COUNT设置为1。表A中的TRT_PROCEDURE列值已更改,将TRT_UPD_COUNT加1作为旧过程值。

通过执行几个INSERT,DELETE和UPDATE进行测试,然后显示表B。

更新:每当将trt_procedure的值插入表B中时,第二个相同的trt_procedure(例如'88 -20')就不能正确地计入其指定的计数字段中。不知道哪里出了问题。

TABLE A
Name    Null     Type
TRT_ID  NOT NULL NUMBER(3)
PAT_NBR          NUMBER(4)
PHYS_ID          NUMBER(3)
TRT_PROCEDURE    VARCHAR2(5)
TRT_DATE         DATE


TABLE B
Name          Null     Type
TRT_PROCEDURE NOT NULL VARCHAR2(5)
TRT_INS_COUNT          NUMBER(3)
TRT_DEL_COUNT          NUMBER(3)
TRT_UPD_COUNT          NUMBER(3)

 TEST SAMPLES
  INSERT INTO A VALUES (11, 8031,101,'88-20',sysdate );
  INSERT INTO A VALUES (12, 5872,101,'60-00',sysdate );
  UPDATE A SET trt_procedure = '88-20' WHERE trt_id=6;
   /*row trt_id =6 cloumn trt_procedure old value '54-60'
    new value '88-20', which means Table B row '88-20' and
    row '54-60 both trt_upd_count should add 1*/

  DELETE FROM A WHERE trt_id=1; 
  /*row trt_id =1 cloumn trt_procedure value also '88-20', which means
    that Table B row '88-20' trt_del_count should also add 1*/

CREATE OR REPLACE TRIGGER trt_stats_trg
BEFORE INSERT OR UPDATE OR DELETE OF TRT_procedure ON A FOR EACH ROW
BEGIN
  IF INSERTING THEN
    UPDATE B SET trt_ins_count = trt_ins_count+1
    WHERE B.trt_procedure = :new.trt_procedure;
    IF SQL%NOTFOUND THEN
    INSERT INTO B (trt_procedure, trt_ins_count)
    VALUES (:new.trt_procedure, 1);
    END IF;

 ELSIF UPDATING THEN
   UPDATE B SET trt_upd_count = trt_upd_count+1
   WHERE B.trt_procedure = :old.trt_procedure;
   IF SQL%NOTFOUND THEN
   INSERT INTO B (trt_procedure, trt_upd_count)
   VALUES (:old.trt_procedure, 1);
   END IF;
   UPDATE B SET trt_upd_count = trt_upd_count+1
   WHERE B.trt_procedure = :new.trt_procedure;
   IF SQL%NOTFOUND THEN
   INSERT INTO B (trt_procedure, trt_upd_count)
   VALUES (:new.trt_procedure, 1);
   END IF;

 ELSIF DELETING THEN
   UPDATE B SET trt_del_count = trt_del_count+1
   WHERE B.trt_procedure = :old.trt_procedure;
   IF SQL%NOTFOUND THEN
   INSERT INTO B (trt_procedure, trt_del_count)
   VALUES (:old.trt_procedure, 1);
   END IF;
 END IF;
END trt_stats_trg;
塔德·哈里森

解决了一些问题。

表格:

create table a(
  TRT_ID  NUMBER(3) NOT NULL ,
  PAT_NBR          NUMBER(4),
  PHYS_ID          NUMBER(3),
  TRT_PROCEDURE    VARCHAR2(5),
  TRT_DATE         DATE
);
create table b(
  TRT_PROCEDURE VARCHAR2(5) NOT NULL,
  TRT_INS_COUNT          NUMBER(3),
  TRT_DEL_COUNT          NUMBER(3),
  TRT_UPD_COUNT          NUMBER(3)
);

和触发

CREATE OR REPLACE TRIGGER trt_stats_trg
BEFORE INSERT OR UPDATE OR DELETE ON A FOR EACH ROW
BEGIN
  IF INSERTING THEN
    UPDATE B SET trt_ins_count = nvl(trt_ins_count,0)+1
      WHERE B.trt_procedure = :new.trt_procedure;
    IF SQL%NOTFOUND THEN
      INSERT INTO B (trt_procedure, trt_ins_count)
      VALUES (:new.trt_procedure, 1);
    END IF;

 ELSIF UPDATING('TRT_PROCEDURE') THEN
   if nvl(:old.trt_procedure, 'X') <> nvl(:new.trt_procedure, 'X') then
     UPDATE B SET trt_upd_count = nvl(trt_upd_count,0)+1
       WHERE B.trt_procedure = :old.trt_procedure;
     IF SQL%NOTFOUND THEN
       INSERT INTO B (trt_procedure, trt_upd_count)
       VALUES (:old.trt_procedure, 1);
     END IF;
     UPDATE B SET trt_upd_count = nvl(trt_upd_count,0)+1
       WHERE B.trt_procedure = :new.trt_procedure;
     IF SQL%NOTFOUND THEN
       INSERT INTO B (trt_procedure, trt_upd_count)
       VALUES (:new.trt_procedure, 1);
     END IF;
   end if;
 ELSIF DELETING THEN
   UPDATE B SET trt_del_count = nvl(trt_del_count, 0)+1
   WHERE B.trt_procedure = :old.trt_procedure;
   IF SQL%NOTFOUND THEN
     INSERT INTO B (trt_procedure, trt_del_count)
     VALUES (:old.trt_procedure, 1);
   END IF;
 END IF;
END trt_stats_trg;
/

关键点:

  • 您可以UPDATING('COLUMN_NAME')用来检测SQL何时影响特定列。

  • 当为时UPDATING,您可能希望检查未更改的更新,其中将值“ ABC”的列更新为“ ABC”。这通常发生在仅将所有列都包含在更新中的框架中,即使它们并没有真正改变。使用类似的东西来检测到这一点if nvl(:old.trt_procedure, 'X') <> nvl(:new.trt_procedure, 'X') then

  • TableB没有计数的默认值,因此当原始触发器尝试更新table时B,它成功...更新NULLNULL,因为将1加到就会发生这种情况NULL这可以通过为0表中的列分配默认值或使用NVL(trt_upd_count,0) + 1代替来解决trt_upd_count + 1

  • 最后,请注意:new和的用法:old在此触发条件下,它们似乎是正确的,但这取决于您的业务案例。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Oracle中的PL / SQL触发器

如何在Oracle PL / SQL中实现AFTER INSERT触发器?

触发器在Oracle PL / SQL中无法正确执行

Oracle中的PL / SQL触发器错误

如何正确处理PL SQL中的触发器?

如何在PL / SQL中删除触发器中的约束?

我如何在 pl/sql 中解决这个触发器?

Oracle PL / SQL触发器-捕获名称错误的插入

涉及多表Oracle、PL/SQL的触发器

更新不同表的 Oracle PL/SQL 触发器

更新Oracle触发器之前的问题[PL / SQL]

PL / SQL:如何启用架构中的所有触发器?

如何在PL / SQL中创建可以创建限制的触发器,使其只能放入1个字符?

如何修复SQL Oracle中未触发的基本触发器

在pl / sql中触发触发器引发错误

如何拆分设置值并在触发器PL / SQL中插入每一行?

如何在SQL Server中的触发器中修复If条件与回滚事务

Oracle PL/SQL 触发器:在更新语句后自动重置列值

Oracle PL / SQL从触发器的:NEW中选择所有列

插入之前的PL / SQL Oracle触发器无法获取新的唯一主ID

Oracle PL/SQL 级联触发器删除未按预期工作

PL / SQL触发器-行触发器

在 PL-SQL 上更改之前如何获取视图/触发器?

如何在Java或Oracle PL / SQL中读取DBase文件

如何在Oracle PL / SQL中处理“超过请求的行数”

如何在 Oracle (PL/SQL) 中创建动态 where 子句

如何在 JSON 路径(Oracle PL SQL)中插入变量?

替换PL / SQL触发器中的子查询

在 PL/SQL 触发器中查找 JSON 数组的长度