觸發器 差之毫釐謬以千里

2021-07-11 21:56:33 字數 2207 閱讀 4734

最近在學習資料庫的相關知識(啊,啊,啊,我不想說我是為了準備考試,否則好丟人啊。。。)

課本名:《全國計算機等級考試**教程–資料庫技術 2023年版》

高等教育出版社

剛學習到關於觸發器的知識,

發現書上有乙個致命的錯誤(哈哈,致命是昨天剛學到的詞彙)

課本164頁,第八章,在介紹觸發器的時候

舉的第乙個例子:建立後觸發型觸發器

因為少了乙個where條件,會將所有商品的庫存量全部進行修改!!

*****>

背景:

table_salebilldetail 表達的是銷售單據明細表

其主鍵為:salebillid 銷售單據id

goodsid 商品id

另外還有乙個屬性:quantity 表達商品銷售的數量

table_goods 商品表

主鍵:goodsid 商品id

屬性值: totalstorage 商品的庫存數量

*****>

要求:

當銷售單據明細表中的商品銷售數量大於此商品的庫存數量(商品表中)時,撤銷此次商品的銷售並提示錯誤。如果銷售數量小於庫存數量,則在插入銷售單據明細記錄時,同時修改此商品的庫存數量。

*****>

課本的**如下:

create trigger trigger_1 on table_salebilldetail for insert

asif 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

asif 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的內容。。。。

觸發器 mysql觸發器

觸發器是一種特殊的儲存過程,它在插入 刪除或修改特定表中的資料時觸發執行,它比資料庫本身標準的功能有更精細和更複雜的資料控制能力。和儲存過程一樣,很少使用。1 觸發器的作用 2 建立觸發器 建立測試環境 mysql create database test db query ok,1 row aff...

觸發器(五 復合觸發器)

oracle11g開始提供了一種復合觸發器,簡單的說就是支援把語句級和行級觸發器組合在一起。實際應用場景不多,這裡就做個記錄。與單個觸發器語法有所區別 1.單個觸發器的頭部是 before after 動作 on 物件 for 觸發級別 而組合觸發器的頭部是 for 動作 on 物件 compoun...

mysql觸發器when MySQL觸發器

set quoted identifier on goset ansi nulls on goalter trigger trg risks on dbo.projectrisk for insert,update asbegin update projectrisk set classificat...