循环触发器

时间:2012-02-26 20:56:16

标签: oracle loops triggers for-loop

我正在尝试实现一个触发器来搜索表上的值,如果它检查了condtion,则插入另一个表中。触发器如下所示:

TRIGGER DISTANCIA
AFTER INSERT ON OBSERVACION FOR EACH ROW
DECLARE
importe_multa NUMBER (3,0);
BEGIN
 FOR ROW IN (SELECT fecha_foto, hora_foto, pto_km_radar, sentido_radar, carretera_foto FROM OBSERVACION) LOOP
    IF((ROW.fecha_foto = :NEW.fecha_foto)
    AND
    (ROW.carretera_foto= :NEW.carretera_foto)
    AND
    (ROW.pto_km_radar=:NEW.pto_km_radar)
    AND
    (ROW.sentido_radar=:NEW.sentido_radar))
    THEN

    IF(ROW.hora_foto<:NEW.hora_foto-3,6/86400)
    THEN
    importe_multa:= (:NEW.hora_foto - ROW.hora_foto - 3,6/86400)*100;
    END IF;
    IF(:NEW.hora_foto < ROW.hora_foto-3,6/86400)
    THEN
    importe_multa:= (ROW.hora_foto - :NEW.hora_foto - 3,6/86400)*100;
    END IF;

   IF(importe_multa IS NOT NULL)
   THEN
     --Introducimos el valor en el campo.
     INSERT INTO SANCION(importe, fecha_foto, hora_foto, coche, tipo)
     VALUES
     (importe_multa, :NEW.fecha_foto, :NEW.hora_foto, :NEW.coche, '2');
     END IF;
    END IF;
END LOOP;
END;

当我尝试编译SQLDeveloper软件时会抛出此错误:

ORA-01008: Not all variables bound.

我是否正确引用OBSERVACION中的变量?

1 个答案:

答案 0 :(得分:0)

1)OBSERVACION上的行级触发器无法查询OBSERVACION表。如果你这样做,你将会发生变异触发错误。所以这种方法基本上是有问题的。

2)我希望您收到编译错误,因为您需要使用小数点作为分隔符来表示十进制数字,而不是逗号。逗号用于将参数分隔为函数。

3)如果确实想要在触发器中实现这种逻辑而不是将它放在它真正属于的过程中,那么你需要解决变异触发错误系列触发器。这将使您的代码变得更加复杂,更难以遵循,并且更难以调试。但它允许您仅使用触发器来执行此操作。

CREATE OR REPLACE PACKAGE pkg_new_rows
AS
  TYPE typ_new_row_array 
    IS TABLE OF rowid;
  g_new_rows typ_new_row_array;
END;

CREATE OR REPLACE TRIGGER trg_before_statement
  BEFORE INSERT ON OBSERVACION
DECLARE
BEGIN
  pkg_new_rows.g_new_rows := new pkg_new_rows.typ_new_row_array();
END;

CREATE OR REPLACE TRIGGER trg_before_row
  BEFORE INSERT ON observacion
  FOR EACH ROW
DECLARE
BEGIN
  pkg_new_rows.g_new_rows.extend;
  pkg_new_rows.g_new_rows( pkg_new_rows.g_new_rows.count ) := :new.rowid;
END;

CREATE OR REPLACE TRIGGER trg_after_statement
  AFTER INSERT ON observacion
DECLARE 
  l_row observacion%rowtype;
BEGIN
  FOR i IN 1 .. pkg_new_rows.g_new_rows.count
  LOOP
    SELECT *
      INTO l_row
      FROM observacion
     WHERE rowid := pkg_new_rows.g_new_rows(i);

   <<implement your logic by querying the other rows of the OBSERVACION table
     and comparing that to the data in the l_row record>>
  END LOOP;
END;