一、创建两个表,一个库存表GoodsStore,一个出库纪录表GoodsStoreOut如下:
Create table GoodsStore(GoodsNo int,GoodsCount int);
Create table GoodsStoreOut(GoodsNo int,GoodsCount int,OutDate date default sysdate);二、库存表GoodsStore中有一条数据
Insert into GoodsStore values(101,50);
三、出库的纪录都保存在GoodsStore中,现在在出库表GoodsStoreOut中插入一条数据,要求创建一个触发器,在GoodsStore表中减少相应的出库数量,但是我们知道,出库的数量不能大于库存的数量,我定义的触发器如下:Create or Replace trigger tg_GoodsOutStore
After insert on GoodsStoreOut
For Each Row 
Begin
if :Old.goodsCount-:New.goodsCount>0 then 
update GoodsStore Set goodsCount=goodsCount-:new.goodsCount
where goodNo=:new.goodsNo;
DBMS_output.put_line('本次出库商品编号为:'||:new.goodsNo||' '||'出库数量为:'||to_char(:new.goodsCount));
Else
DBMS_output.put_line('出库的数量不能大于库存的数量'); Rollback;
End if;
End;
四、问题
1、我创建完触发器执行以后,无论怎样,总是会执行else下面的语句
2、系统还会提示,rollback不能运行在触发器中
请问这是什么原因阿?有没有人给指点一下,不甚感激!

解决方案 »

  1.   

    这里存在两个问题:
    1、如果是Insert的触发器,它的:Old值都是NULL的,所以‘:Old.goodsCount-:New.goodsCount>0'应该有点问题(本人没有测试过,而且这样写会不会好点?Old.goodsCount>:New.goodsCount)。或者是LZ定义触发器的时候笔误了,只是定义了Insert,没有定义Update。
    2、在Trigger中不能使用像rollback、commit等这样的事务操作语句。,利用raise_application_error(-20001,'出库的数量不能大于库存的数量')引发异常,使GoodsStoreOut表不能提交,GoodsStore表自然就不会提交了。------------------------
    本人在深圳,正在找工作中,刚刚自学过PL/SQL,对Oracle体系结构也有些了解;熟悉MS SQL Server 2000;熟悉Delphi,了解Java、JSP。希望找数据库开发方面的工作
      

  2.   

    搂主之意是肯定有库存,然后才能出库。所以一定是UPDATE,而且要用BEFORE UPDATE, if 成立的话最好加上COMMIT。楼主尝试下面:Create or Replace trigger tg_GoodsOutStore
    BEFORE UPDATE on GoodsStoreOut
    For Each Row 
    Begin
    if :Old.goodsCount-:New.goodsCount>0 then 
    update GoodsStore Set goodsCount=goodsCount-:new.goodsCount
    where goodNo=:new.goodsNo;
    DBMS_output.put_line('本次出库商品编号为:'||:new.goodsNo||' '||'出库数量为:'||to_char(:new.goodsCount));
    COMMIT;
    Else
    DBMS_output.put_line('出库的数量不能大于库存的数量'); Rollback;
    End if;
    End;
      

  3.   

    多谢楼上两位的答案,但是好像还是不能阻止GoodsStoreOut会插入一条数据,确实在触发器中不能用RollBack和commit两个语句。
        现在的问题就是,如何让数据库知道违法了逻辑,而自动将已经插入GoodsStoreOut表中的数据回滚呢?
      

  4.   

    alter table GOODSSTORE
    add constraint check001
    check (GOODSCOUNT>=0);
      

  5.   

    Create Or Replace Trigger tg_GoodsOutStore
    After insert on GoodsStoreOut
    For Each Row
    BEGIN
    UPDATE GOODSSTORE
     SET GOODSCOUNT = GOODSCOUNT - :NEW.GOODSCOUNT
     WHERE GOODSNO = :NEW.GOODSNO;
    END;
      

  6.   

    创建一个存储过程往GoodsOutStore表中插入数据,保证插入的时候出库的产品数量一定小于库存量,如果超过库存量则回滚不执行插入操作 :CREATE OR REPLACE PROCEDURE PR_AUTO_TEST_SON(GOODSNO IN INT ,GOODSCount IN INT) IS
      PRAGMA AUTONOMOUS_TRANSACTION;
    myexcept exception;
    OLDCOUNT INT DEFAULT 0;
    BEGIN
      SELECT GOODSCOUNT INTO OLDCOUNT FROM GoodsStore WHERE GOODSNO = GOODSNO FOR UPDATE NOWAIT;
      IF OLDCOUNT >= GOODSCount THEN 
         INSERT INTO GoodsStoreOut VALUES (GOODSNO,GOODSCount,SYSDATE );
         DBMS_output.put_line('本次出库商品编号为:'||GOODSNO||' '||'出库数量为:'||to_char(GOODSCount));
         COMMIT;
      ELSE 
         RAISE myexcept;
      END IF;
      EXCEPTION
      WHEN myexcept THEN
        ROLLBACK;
        DBMS_output.put_line('出库的数量不能大于库存的数量');
    END PR_AUTO_TEST_SON;创建触发器控制出库产品数量对库存产品数量的影响:
    Create or Replace trigger tg_GoodsOutStore
    AFTER insert on GoodsStoreOut
    For Each Row
    DECLARE 
    Begin
      update GoodsStore Set goodsCount=goodsCount-:new.goodsCount
        where goodsNo=:new.goodsNo;
      DBMS_output.put_line('本次出库商品编号为:'||:new.goodsNo||' '||'出库数量为:'||to_char(:new.goodsCount));
    End;
      

  7.   

    SQL> SELECT * FROM GoodsStore;   GOODSNO GOODSCOUNT
    ---------- ----------
           101         37SQL> SELECT * FROM GoodsStoreOut;   GOODSNO GOODSCOUNT OUTDATE
    ---------- ---------- -------------------
           101          5 2006-08-21 16:01:07
           101          8 2006-08-21 16:06:16SQL> EXEC PR_AUTO_TEST_SON(101,50);出库的数量不能大于库存的数量
    PL/SQL 过程已成功完成。SQL> SELECT * FROM GoodsStore;   GOODSNO GOODSCOUNT
    ---------- ----------
           101         37SQL> SELECT * FROM GoodsStoreOut;   GOODSNO GOODSCOUNT OUTDATE
    ---------- ---------- -------------------
           101          5 2006-08-21 16:01:07
           101          8 2006-08-21 16:06:16SQL> EXEC PR_AUTO_TEST_SON(101,10);
    本次出库商品编号为:101 出库数量为:10
    本次出库商品编号为:101 出库数量为:10PL/SQL 过程已成功完成。SQL> SELECT * FROM GoodsStoreOut;   GOODSNO GOODSCOUNT OUTDATE
    ---------- ---------- -------------------
           101         10 2006-08-21 16:07:49
           101          5 2006-08-21 16:01:07
           101          8 2006-08-21 16:06:16SQL> SELECT * FROM GoodsStore;   GOODSNO GOODSCOUNT
    ---------- ----------
           101         27