1. 程式人生 > >mysql資料庫--觸發器和程式碼執行結構

mysql資料庫--觸發器和程式碼執行結構

需求:有兩張表,一張訂單表一張商品表,每生成一個訂單商品的庫存要減少。

-- 建立表
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;