SQL触发器减少另一个表

时间:2014-03-19 18:50:55

标签: sql oracle plsql

我为DVD商店创建了一个数据库,其中包含一个电影表,用于保存有关电影和可用副本的信息以及销售表。我已经为Film和Sale表创建了序列,使用以下代码分别自动递增主键FILM_ID和SALE_TRANSACTION_REF。

CREATE SEQUENCE Film_Seq
MINVALUE 1
START WITH 1
INCREMENT BY 1
NOCACHE;

CREATE OR REPLACE TRIGGER New_Film 
BEFORE INSERT ON FILM 
FOR EACH ROW

BEGIN
SELECT Film_Seq.NEXTVAL
INTO   :new.FILM_ID
FROM   dual;
END;
/

这似乎很方便,但是当我尝试使用触发器在使用以下代码进行销售后减少胶片中COPIES_AVAILABLE属性时,我收到错误:

CREATE OR REPLACE TRIGGER After_Sale 
AFTER INSERT ON SALE 
DECLARE
ID NUMBER(38) := Sale_Seq.CURRVAL;
BEGIN
    UPDATE FILM
    SET COPIES_AVAILABLE = COPIES_AVAILABLE - 1
    FROM FILM, SALE
    WHERE FILM.FILM_ID = SALE.FILM_ID 
    AND (SALE.SALE_TRANSACTION_REF = ID);
END;
/

我实际上得到两个错误,第一个错误与声明语句相关,即

4/2    PL/SQL: SQL Statement ignored

第二个与UPDATE语句有关,它是

6/2    PL/SQL: ORA-00933: SQL command not properly ended

我已经破坏了我的大脑试图以不同的方式构建这个陈述,并且已经搜索了文档但似乎无法找到答案,并且非常感谢帮助。

另外,看看我的问题可能并不明显,但我已经创建了sale_seq。

对不起,我在这里尝试实现的目标可能并不明显。每当电影被出售并添加到销售表中时,我想自动减少电影表中相应电影的Copie_Available,所以如果我省略了AND AND (SALE.SALE_TRANSACTION_REF = Sale_Seq.CURRVAL)子句,触发器将会成为盛大的,但会减少电影表中所有电影的所有副本都是不正确的。

2 个答案:

答案 0 :(得分:1)

尝试这样:

CREATE OR REPLACE TRIGGER After_Sale 
AFTER INSERT ON SALE 
FOR EACH ROW
BEGIN
    UPDATE FILM
    SET COPIES_AVAILABLE = COPIES_AVAILABLE - 1
    WHERE FILM.FILM_ID = :NEW.FILM_ID
END;

答案 1 :(得分:0)

为什么要将COPIES_AVAILABLE保存到您的数据库中。如果你想知道可用的副本,为什么不贬低[例如库存中的所有副本] - [所有出售的副本]。