1. 程式人生 > >關於mysql中觸發器的使用

關於mysql中觸發器的使用

觸發器
    在當前的表上,設定一個對每行資料的一個監聽器,監聽相關事件,每當事件觸發時,就會執行一段由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;