如何从Oracle 10g获取被称为触发器的表字段?

时间:2014-06-09 12:00:59

标签: oracle triggers average

当我添加或更改其中的一行时,我想计算给定字段(PRA_NUM)的表格列(PRA_COEFF)(RAPPORT_VISITE)中的值的平均值。然后我想将这个值保存在另一个表(PRACTITIONER)中,上面给出PRA_NUM值PRA_NUM的行。

CREATE TABLE "RAPPORT_VISITE" 
(
"RAP_NUM" NUMBER (10,0), 
"PRA_NUM" NUMBER (10,0), 
"PRA_COEFF" NUMBER (10,0), 
) 

CREATE TABLE "PRATICIEN" 
(
"PRA_NUM" NUMBER (10,0), 
"PRA_COEFCONF" NUMBER 
) 

在添加或修改RAPPORT_VISITE表时调用触发器。我尝试过这样,但是我无法检索受触发器影响的行,因此我需要读取PRA_NUM。

create or replace TRIGGER UDPATE_PRAT_COEFCONF
  AFTER INSERT or UPDATE ON RAPPORT_VISITE

  DECLARE
  somme NUMBER;
  nb NUMBER;
  moyenne NUMBER;
  rapport NUMBER;
  pra_id NUMBER;

BEGIN

  /*SELECT MAX(RAP_NUM) INTO rapport FROM RAPPORT_VISITE; // Not want I need in case where I modify a row... */
  SELECT PRA_NUM INTO pra_id FROM RAPPORT_VISITE WHERE RAP_NUM=rapport;
  SELECT SUM(PRA_COEFF) INTO somme FROM RAPPORT_VISITE WHERE PRA_NUM=pra_id;
  SELECT COUNT(*) INTO nb FROM RAPPORT_VISITE WHERE PRA_NUM=pra_id;

  IF (nb != 0) THEN
    moyenne := somme/nb;
    moyenne := TRUNC (moyenne,1);
    UPDATE PRATICIEN SET PRA_COEFCONF=moyenne WHERE PRA_NUM=pra_id;
  END IF;

END;

1 个答案:

答案 0 :(得分:1)

以下是触发器通常具有的2个限制:

  1. 为所有受影响的记录调用时,您不知道究竟发生了什么变化

  2. 为个别记录(FOR EACH ROW)调用时,您可以访问修改后的表格

  3. 要解决这个限制,从Oracle 11g开始,我们可以使用compound trigger

    CREATE OR REPLACE TRIGGER <trigger-name>
    FOR <trigger-action> ON <table-name>
    COMPOUND TRIGGER
    
    -- Global declaration.
    g_global_variable VARCHAR2(10);
    -- block 1
    BEFORE STATEMENT IS
    BEGIN
    NULL; -- Do something here.
    END BEFORE STATEMENT;
    -- block 2
    BEFORE EACH ROW IS
    BEGIN
    NULL; -- Do something here.
    END BEFORE EACH ROW;
    -- block 3
    AFTER EACH ROW IS
    BEGIN
    NULL; -- Do something here.
    END AFTER EACH ROW;
    -- block 4
    AFTER STATEMENT IS
    BEGIN
    NULL; -- Do something here.
    END AFTER STATEMENT;
    
    END <trigger-name>;
    

    看起来这就是你所需要的。在块1中,初始化变量,在块2或3中收集各行的更改,然后在块4中使用该信息创建其余的业务逻辑。


    如果我们受限于10g,那么我们可以使用包变量模拟复合触发器。 此解决方案是有限的,因为包变量是会话的全局变量。如果有一个会话你有2个类似的操作,他们的结果将被合并。

    这是解决方案

    1. 您将有3个独立的触发器,代表上面的触发器中的块1,(2或3)和4。

    2. 您将拥有一个包含变量g_global_variable的包(来自上方)

    3. 3个动作:

      1. in trigger for block 1 initiate g_global_variable 
      2. in trigger for block 2 or 3, populate it with actual values
      3. in trigger for block 4, create your logic
      

      当然,g_global_variable可能并不孤单,它可能是记录或收集。