简体   繁体   English

PL SQL触发器不起作用

[英]PL SQL trigger doesn't work

I have written a Trigger which fires on the insert or update of the table bestellung and I want it to change certain things when inserting or updating a file in the table. 我编写了一个触发器,该触发器会在表bestellung的插入或更新时触发,并且我希望它在插入或更新表中的文件时更改某些内容。 What I want to change I think you can see from the code. 我想更改的内容我想您可以从代码中看到。

I am working with APEX right now and when I try to insert an Order he always throws me the Error the Table is right now being changed and that the trigger maybe doesn't see the changes. 我现在正在使用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;​
/

I would use a BEFORE INSERT OR UPDATE trigger instead of an AFTER trigger here. 我会在这里使用BEFORE INSERT OR UPDATE触发器而不是AFTER触发器。 In a BEFORE trigger, you can access and change the values of the affected row before they get inserted or updated, by assigning to :NEW.columnname . BEFORE触发器中,可以通过分配给:NEW.columnname来访问和更改受影响的行的值,然后再插入或更新它们。 This is sufficient for you, as you are only querying/updating data in the row that the trigger has fired for. 这对您就足够了,因为您仅查询/更新触发器为其触发的行中的数据。

This also avoids the 'table XYZ is mutating; 这也避免了表XYZ发生变异; trigger/function may not see it' error, because we are no longer attempting to query or update the table during a trigger that updates it. 触发器/函数可能看不到错误,因为我们不再试图在更新表的触发器期间查询或更新表。

I've had a go at rewriting your trigger as a BEFORE trigger. 我可以将触发器改写为触发器BEFORE Please note that I haven't tested that it works, other than creating a suitable table and verifying that the trigger compiles: 请注意,除了创建合适的表并验证触发器是否可以编译外,我还没有进行过测试:

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;
/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM