最近在学习数据库的相关知识(啊,啊,啊,我不想说我是为了准备考试,否则好丢人啊。。。)
课本名:《全国计算机等级考试三级教程–数据库技术 2013年版》
高等教育出版社
刚学习到关于触发器的知识,
发现书上有一个致命的错误(哈哈,致命是昨天刚学到的词汇)
课本164页,第八章,在介绍触发器的时候
举的第一个例子:创建后触发型触发器
因为少了一个where条件,会将所有商品的库存量全部进行修改!!
=====>
背景:
table_salebilldetail 表达的是销售单据明细表
其主键为:salebillid 销售单据id
goodsid 商品id
另外还有一个属性:quantity 表达商品销售的数量
table_goods 商品表
主键:goodsid 商品id
属性值: totalstorage 商品的库存数量
=====>
要求:
当销售单据明细表中的商品销售数量大于此商品的库存数量(商品表中)时,撤销此次商品的销售并提示错误。如果销售数量小于库存数量,则在插入销售单据明细记录时,同时修改此商品的库存数量。
=====>
课本的代码如下:
create trigger trigger_1 on table_salebilldetail for insert
as
if exists(select 1 from inserted a join table_goods b on a.goodsid = b.goodsid where a.quantity > b.totalstorage)
begin
rollback;
print ‘not encough to sale!’
end
else
update table_goods
set totalstorage = totalstorage - (select quantity from inserted)
=====>
啊,啊, 啊
发现问题没有?
如果 quantity < totalstorage 时,进入else语句
接下来呢?
接下来是,所有商品的totalstorage 都被 减了 quantity的量啦!!
这是什么情况?
这是一件多么可怕的事情!!
如果书上的这段代码被用到实际应用系统中,老总估计要疯了。。。。
=====>
正确的语法应该是这样的:
create trigger trigger_1 on table_salebilldetail for insert
as
if exists(select 1 from inserted a join table_goods b on a.goodsid = b.goodsid where a.quantity > b.totalstorage)
begin
rollback;
print ‘not encough to sale!’
end
else
update table_goods
set totalstorage = totalstorage - (select quantity from inserted)
where goodsid = (select goodsid from inserted);
=====>
看到区别了没有?
其实就多了一句 where 条件啊!
这样就只减少了 inserted 进来的商品的 totalstorage的量!!
=====>
写代码,还是要细心细心再细心啊
一定要把逻辑理理清楚,多尝试,多思考
才能真正把代码写好。。
=====>
ps:当然,这里还少了对quantity的判断,因为如果quantity <=0 的话,肯定会进到else中,这样逻辑上就不对了
我们可以在进入else时再进行一次判断:
else if (quantity <=0)
begin
rollback;
print ‘Error for quantity!’;
end
else
下面再接else的内容。。。。