mysql資料庫--觸發器和程式碼執行結構
阿新 • • 發佈:2018-11-26
需求:有兩張表,一張訂單表一張商品表,每生成一個訂單商品的庫存要減少。
-- 建立表 create table my_goods( id int primary key auto_increment, name varchar(20) not null, price decimal(10,2) default 1, inv int comment '庫存數量' )charset utf8; -- 插入資料 insert into my_goods values(null,'ipone',8000,100),(null,'xiaomi',3000,300); -- 建立表 create table my_order( id int primary key auto_increment, g_id int not null comment '商品ID', g_number int comment '商品數量' )charset utf8;
觸發器
觸發器:trigger,事先為某張表繫結好一段程式碼,當表中的某些內容發生改變的時候(增刪改),系統會自動觸發程式碼執行。
觸發器:事件型別,觸發時間,觸發物件
事件型別:增刪改insert,delete和update
觸發時間:前後before和after
觸發物件:表中的每一條記錄(行)
一張表中只可以擁有一種觸發時間的一種型別的觸發器,最多一張表可以有六個觸發器。
建立觸發器:
在mysql高階結構中,沒有大括號,都是用對應的字串代替。(表是低階結構) 觸發器基本語法: -- 臨時修改語句結束符 delimiter 自定義符號(假設是$$):後續程式碼中只有碰到自定義符號才算結束。 create trigger 觸發器名字 觸發時間 事件型別 on表名 for each row begin -- 代表左大括號:開始 --裡面就是觸發器的內容 ,每行內容都必須使用語句結束符:分號 end -- 代表右大括號:結束 -- 語句結束符 自定義符號(這裡也要寫$$) -- 將臨時修改修正過來 delimiter ;
建立觸發器解決需求:
-- 建立觸發器:保證訂單生成一個,商品庫存減少一個
-- 臨時修改語句結束符
delimiter $$
create trigger after_order after insert on my_order for each row
begin
-- 觸發內容開始
update my_goods set inv = inv - 1 where id = 2;
end
-- 結束觸發器
$$
-- 修改臨時語句結束符
delimiter ;
檢視觸發器:
檢視所有觸發器或者模糊匹配: show triggers [like 'pattern'] -- 檢視所有觸發器 show triggers\G
可以檢視觸發器建立語句
show create trigger 觸發器名字;
所有的觸發器都會儲存在一張表中:information_schema.triggers
使用觸發器:
觸發器:不需要手動呼叫,而是當某種情況發生時會自動觸發(訂單裡面插入記錄之後)
修改觸發器&刪除觸發器
觸發器不能修改只可以先刪除再新增
drop trigger 觸發器名字;
-- 刪除觸發器
drop trigger after_order;
解決剛才觸發器產生的問題:觸發器記錄
觸發器記錄:不管觸發器是否觸發了,只要當某種操作準備執行,系統就會將當前要操作的記錄的當前狀態和即將執行之後
的新狀態分別保留下來供觸發器使用,其中要操作的當前狀態儲存到old中,操作之後的可能形態儲存給new。
old代表的是舊記錄,new代表的是新紀錄
刪除的時候是沒有new的,插入的時候沒有old
old和new都是代表記錄本身,任何一條記錄除了有資料還有欄位名字
使用方式:old.欄位名 / new.欄位名(new代表的是假設發生之後的結果)
檢視觸發器的效果:
程式碼執行結構:
程式碼執行結構有三種:順序結構,分支結構,迴圈結構
分支結構
分支結構:實現準備多個程式碼塊,按照條件選擇性的執行某段程式碼。
在MySQL中只有if分支,基本語法:
if 條件判斷 then
-- 滿足條件要執行的程式碼
else
-- 不滿足條件要執行的程式碼
end if;
觸發器結合if分支:判斷商品庫存是否足夠不夠則不能生成訂單
-- 臨時修改語句結束符
delimiter $$
create trigger before_order before insert on my_order for each row
begin
-- 判斷商品內容是否足夠,獲取商品庫存
select inv from my_goods where id = new.g_id into @inv;
-- 比較庫存
if @inv < new.g_number then
-- 庫存不夠,但是觸發器不能提供一個能夠阻止事件發生的能力(只可以人為暴力製造報錯)
insert into XXX values(XXX);
end if;
end
-- 結束觸發器
$$
-- 修改臨時語句結束符
delimiter ;
插入訂單檢測觸發器程式碼執行:
-- 插入超出庫存的訂單
insert into my_order values(null,1,10000);
迴圈結構
迴圈結構:某段程式碼在指定條件執行重複執行。
while迴圈(沒有for迴圈)語法格式:
while 條件判斷 do
-- 滿足條件要執行的程式碼,變更迴圈條件
end while;
迴圈控制:在迴圈內部進行迴圈的判斷和控制,在MySQL中沒有continue和break這種方式,但是有
iterate:迭代,類似continue,後面的程式碼不會執行,迴圈重新來過
leave:離開,類似於break,整個迴圈退出
使用方式:iterate/leave 迴圈名字;
-- 定義迴圈名字
迴圈名字:while 條件 do
-- 迴圈體,迴圈控制
leave/iterate 迴圈名字;
end while;