一、创建两个表,一个库存表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不能运行在触发器中
请问这是什么原因阿?有没有人给指点一下,不甚感激!
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、如果是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。希望找数据库开发方面的工作
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;
现在的问题就是,如何让数据库知道违法了逻辑,而自动将已经插入GoodsStoreOut表中的数据回滚呢?
add constraint check001
check (GOODSCOUNT>=0);
After insert on GoodsStoreOut
For Each Row
BEGIN
UPDATE GOODSSTORE
SET GOODSCOUNT = GOODSCOUNT - :NEW.GOODSCOUNT
WHERE GOODSNO = :NEW.GOODSNO;
END;
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;
---------- ----------
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