PL SQL触发器不起作用

时间:2014-01-31 19:48:06

标签: sql plsql

我编写了一个触发器,它触发了表bestellung的插入或更新,我希望它在插入或更新表中的文件时更改某些内容。我想改变的是我认为你可以从代码中看到。

我现在正在与APEX合作,当我尝试插入订单时,他总是抛出错误,表现在正在被更改,触发器可能看不到更改。

create or replace trigger bestellschluss_iuar
after insert or update on bestellung
for each row
DECLARE 
v_date2 DATE;
v_hour number;

BEGIN

select bestelldatum + 2 into v_date2 from bestellung where bestellid = :new.bestellid;
select EXTRACT(HOUR FROM TO_TIMESTAMP(SYSDATE))into v_hour FROM DUAL;       

IF :NEW.zieldatum IS NULL THEN
    IF v_hour > 17 THEN
        UPDATE bestellung
        SET zieldatum = bestelldatum + 3
        WHERE bestellid = :NEW.bestellid;
    ELSE
        UPDATE bestellung -- bestellung means order
        SET zieldatum = bestelldatum + 2 --and this means deliverydate = orderdate +2
        WHERE bestellid = :NEW.bestellid;
    END IF;
ELSIF v_date2 > :NEW.zieldatum THEN
        raise_application_error(-22501, 'Bestellungen für dieses Datum nicht möglich da zu Kurze Lieferzeit');
ELSIF (v_date2 = :NEW.zieldatum) AND v_hour > 18 THEN
        raise_application_error(-22502, 'Bestellungen um diese Uhrzeit für diesen Tag nicht mehr möglich');
END IF;
END;​
/

1 个答案:

答案 0 :(得分:3)

我会在这里使用BEFORE INSERT OR UPDATE触发器而不是AFTER触发器。在BEFORE触发器中,您可以通过分配:NEW.columnname来访问和更改受影响行的插入或更新之前的值。这对您来说已经足够了,因为您只是查询/更新触发器触发的行中的数据。

这也避免了'表XYZ正在变异;触发器/函数可能看不到它'错误,因为我们不再尝试在更新它的触发器期间查询或更新表。

我已经将你的触发器重写为BEFORE触发器了。请注意,我没有测试它是否有效,除了创建一个合适的表并验证触发器编译:

create or replace trigger bestellschluss_iubr
  before insert or update on bestellung
  for each row
DECLARE 
  v_date2 DATE;
  v_hour number;

BEGIN
  v_date2 := :NEW.bestelldatum + 2;
  v_hour := EXTRACT(HOUR FROM SYSTIMESTAMP);

  IF :NEW.zieldatum IS NULL THEN
    IF v_hour > 17 THEN
      :NEW.zieldatum := :NEW.bestelldatum + 3;
    ELSE
      :NEW.zieldatum := :NEW.bestelldatum + 2;
    END IF;
  ELSIF v_date2 > :NEW.zieldatum THEN
    raise_application_error(-22501, 'Bestellungen für dieses Datum nicht möglich da zu Kurze Lieferzeit');
  ELSIF (v_date2 = :NEW.zieldatum) AND v_hour > 18 THEN
    raise_application_error(-22502, 'Bestellungen um diese Uhrzeit für diesen Tag nicht mehr möglich');
  END IF;
END;
/