在插入触发器之前未按预期运行

时间:2014-10-21 15:23:53

标签: oracle triggers insert

我有一张叫做电影的桌子:

  CREATE TABLE film (
  film_id NUMBER(5) NOT NULL,
  title varchar2(255),
  description varchar2(255),
  release_year NUMBER(4) DEFAULT NULL,
  language_id NUMBER(3) NOT NULL,
  original_language_id NUMBER(3) DEFAULT NULL,
  rental_duration NUMBER(3) DEFAULT 3 NOT NULL,
  rental_rate NUMBER(4,2) DEFAULT '4.99',
  length NUMBER(5) DEFAULT NULL,
  replacement_cost NUMBER(5,2) DEFAULT '19.99' NOT NULL,
  rating varchar2(8) DEFAULT 'G',
  special_features varchar2(255) DEFAULT NULL
  );

我试图制作一个触发器,根据它的特殊功能(只能有一个)增加电影的租金率。我想出了以下触发器(对于oracle而且编译没有错误)

CREATE OR REPLACE TRIGGER INCREASE_RENTAL_RATE
BEFORE INSERT ON FILM
FOR EACH ROW
DECLARE
    change number(4,2);
BEGIN
DBMS_OUTPUT.put_line('mytrigger STARTING');
IF (:NEW.SPECIAL_FEATURES = 'Trailers') THEN
    change := 0.1;
    DBMS_OUTPUT.put_line('Trailer Read');
END IF;
IF (:NEW.SPECIAL_FEATURES = 'Commentaries') THEN
    change := 0.5;
    DBMS_OUTPUT.put_line('Commentary read');
END IF;
IF (:NEW.SPECIAL_FEATURES = 'Deleted Scenes') THEN
    change := 0.2;
    DBMS_OUTPUT.put_line('DS read');
END IF;
IF (:NEW.SPECIAL_FEATURES = 'Behind the Scenes') THEN
    change := 0.2;
    DBMS_OUTPUT.put_line('BS read');
END IF;

DBMS_OUTPUT.put_line('new=' || :NEW.rental_rate);
UPDATE FILM
SET FILM.RENTAL_RATE = FILM.RENTAL_RATE + change
WHERE FILM.FILM_ID = :NEW.FILM_ID;
DBMS_OUTPUT.put_line('new=' || :NEW.rental_rate);
DBMS_OUTPUT.put_line('mytrigger FINISHED');
END;​

由于它没有错误编译,我不知道在哪里寻找问题,但它不起作用,我用了一个虚拟的例子:

   INSERT INTO FILM VALUES(20001, 'SUPREMO BORROWERS', 'An exasdafaf', 1978, 1, NULL, 5, '2.99', 52, '11.99', 'PG-13', 'Trailers');

其中,当我选择film_id = 20001的电影时,租金率为2.99并继续为2.99

以下是收到的输出: “mytrigger开始 预告片阅读 新= 2.99 新= 2.99 mytrigger完成了

插入了1行。“

这意味着它知道它有预告片,但更新无效

有人可以帮我理解为什么吗?

谢谢:)

1 个答案:

答案 0 :(得分:1)

这是一个之前的触发器,并且您正在尝试直接更新即将在表中插入/更新的行(可能尚不存在,如果确实存在,可能会被实际更新再次覆盖) )。而不是表更新,只需更改new伪行的值:

:new.RENTAL_RATE := :new.RENTAL_RATE + change;

修改

根据以下评论,在这种情况下,上述对OP没有效果。但是,以下做了:

SELECT :new.RENTAL_RATE + change INTO :new.RENTAL_RATE FROM DUAL;