關於mysql中觸發器的使用
阿新 • • 發佈:2018-12-19
觸發器 在當前的表上,設定一個對每行資料的一個監聽器,監聽相關事件,每當事件觸發時,就會執行一段由sql完成的一段功能程式碼 觸發事件: insert, delete, update new old : 針對的是觸發的那張表 on 表名 insert : 沒有 old 有new 【對於插入,插入之前什麼都沒有,插入之後才有資料】 update : 有old 有new delete : 有old 沒有new 因為資料的改變不是固定,所以需要獲取觸發程式時的資料 old: 表示事件發生之前的資料, 舊的資料 new: 表示事件發生之後的資料, 新的資料 事件的時機: after(表示執行之後), before(表示執行之前); 事件和時機組合在一起一共有六種事件 before insert, before delete, before update after insert, after delete, after update 監聽的地點: table(表),事件規定在哪個表上的哪個時機的什麼動作上 ************************************************************************************************** 建立觸發器 語法格式 create trigger trigger_name [六種情況] on table_name for each row begin sql statement; end; 刪除觸發器 drop trigger trigger_name; 檢視觸發器 select trigger_name from `information_schema`.TRIGGERS; *************************************************************************************************** drop table if exists seller; create table seller( name varchar(30), money double(8,2) ); insert into seller values('狗娃', 5000); drop table if exists buyer; create table buyer( name varchar(30), money double(8,2) ); insert into buyer values('狗蛋', 1000); 例: 建立觸發器 drop trigger if exists tr_buyer; delimiter $$ create trigger tr_buyer after update on buyer for each row begin update seller set money = money + 10; end$$ delimiter ; update buyer set money = money - 10; 例: 檢視觸發器 select trigger_name from `information_schema`.TRIGGERS; 例: 刪除觸發器 drop trigger [if exists] tr_buyer; ************************************************************************************************** 例: 建立觸發器 drop trigger if exists tr_buyer; delimiter $$ create trigger tr_buyer after update on buyer for each row begin # update seller set money = money + (買家原有的錢 - 買家現在的錢) '買家買東西的錢'; update seller set money = money + (old.money - new.money); end$$ delimiter ; update buyer set money = money - 1000; 例: drop trigger if exists tr_buyer; delimiter $$ create trigger tr_buyer before update on buyer for each row begin if new.money >= 0 then update seller set money = money + (old.money - new.money); else SIGNAL SQLSTATE 'HY000' set MESSAGE_TEXT = '您的金錢不足'; end if; end$$ delimiter ; update buyer set money = money - 2; --如果事件是insert, 則只有new沒有old drop trigger if exists tr_buyer; delimiter $$ create trigger tr_buyer before insert on buyer for each row begin insert into seller values(old.name, old.money); #報錯 end$$ delimiter ; insert into buyer values('狗剩', 1000) --如果事件是delete,則只有old沒有new drop trigger if exists tr_buyer; delimiter $$ create trigger tr_buyer before delete on buyer for each row begin insert into seller values(new.name, new.money); #報錯 end$$ delimiter ; delete from buyer where name = '狗蛋'; ps: 觸發器不能同名 現在mysql只支援一類事件設定一個觸發器 --充錢 取錢 create table yaoye( id int primary key auto_increment, name char(80), age tinyint(4) unsigned ); create table fd( fid int primary key, fname char(80), fage tinyint(4) unsigned ); 針對一個帳號 存錢 取錢 當往yaoye 存錢的時候,要在fd顯示出來 drop trigger if exists mtri; delimiter $$ #更改預設的結束符號為 $$ create trigger mtri before update on yaoye for each row begin declare nowMoney float; # 申明一個變數nowMoney ,資料型別是float select ymoney into nowMoney from yaoye where id = 1; if(old.ymoney - new.ymoney < nowMoney) then update fd set fmoney = fmoney - ( old.ymoney - new.ymoney ) where fid = new.id; # new.ymoney 現在的錢 , old.ymoney 原先的錢 elseif(old.ymoney - new.ymoney > nowMoney) then set new.ymoney = old.ymoney; # end if; end $$ delimiter ; if() then ; elseif then elseif then ...; else sql程式碼 end if; ************************************************************************************************************* mysql函式 條件判斷函式 1: if(expr, v1, v2): 如果expr這個條件成立,則執行v1,否則執行v2; 例: select if(1=0, 1, 0); 2: case when expr1 then v1 when expr2 then v2 else v3 end 例: select stu_no, stu_sex, case when stu_sex='男' then concat(stu_name,'大帥哥') when stu_sex='女' then concat(stu_name,'小美女') else stu_name end as '姓名' from student; 系統資訊函式 1: select version(); 獲取資料庫系統版本號 2: select connection_id(); 獲取資料庫連線數 3: select database()/schema(); 獲取當前資料庫 4: select user(); 獲取當前使用者名稱 加密函式 1: select password(str) 對str加密 2: select md5(str) 對str進行md5的加密 其它 1: inet_aton(ip) 把ip轉化為數值來表示 例: select inet_aton('192.16.70.100'); 2: inet_ntoa(n) 把一個數值轉化ip 例: select inet_ntoa(3222292068); 自定義函式(函式不能返回結果集) 語法格式: create function 函式名(引數列表) returns 返回值型別 begin 函式體; end; 例: 自定義一個返回矩形的面積的函式 delimiter $$ create function rectangle_area(w double, h double) returns double begin declare value double default 0; set value := w*h; return value; end$$ delimiter ; 呼叫: select rectangle_area(3, 100); 自定義函式: 因為官方函式是有限的,所以特殊的需求需要自己創造 語法【不帶引數】: drop function if exists 函式的名字; delimiter $$ create function 函式的名字()returns 資料型別 begin sql語句塊 end $$ delimiter ; 語法【帶引數】: drop function if exists 函式的名字; delimiter $$ create function 函式的名字(引數名字1 資料型別1,引數名字2 資料型別2.....)returns 資料型別 begin sql語句塊 end $$ delimiter ; eg: drop function if exists xiaokun; delimiter $$ create function xiaokun()returns varchar(100) begin return "風度迷彩你好帥!!帥的我想揍你!!"; end $$ delimiter ; 怎麼呼叫 select 函式名(); monkey(num1,num2,opeart); select monkey(23,45,"+"); select monkey(10,45,"*"); select monkey(16,8,"-"); select monkey(16,8,"/"); drop function if exists monkey; delimiter $$ create function monkey(num1 float,num2 float,opeart varchar(100))returns float begin declare ope varchar(80); # 申明變數ope,資料型別是 varchar(80) select trim(opeart) into ope; # 將opeart的值賦給 ope if(ope != "") then if(ope = "+") then return num1 + num2; elseif(ope = "-") then return num1 - num2; elseif ope = "*" then return num1 * num2; elseif ope = "/" then return num1 / num2; end if; else return 0; end if; end $$ delimiter ; 檢視函式 select type, db, name from mysql.proc; select type, db, name from mysql.proc where type = 'FUNCTION'; 刪除函式 drop function rectangle_area;