1. 程式人生 > >Mysql06觸發器,儲存過程

Mysql06觸發器,儲存過程

儲存過程
函式
觸發器

會話變數
 一次會話過程中,使用的變數
 可以自定義任意變數儲存任意資料

set @v1=‘abc’;
select @v1;

 可以訪問資料庫的系統變數
set @@tx_isolation=‘repeatable-read’
set tx_isolation=‘repeatable-read’

儲存過程
 儲存在資料庫伺服器上的一段程式程式碼

建立儲存過程
delimiter // – 自定義結束符
delimiter ; – 重新設定用分號表示結束

create procedure p1()
begin
select * from employees;
end;
//

呼叫儲存過程
call p1();
//
檢視儲存過程
show create procedure p1\G
show procedure status\G
show procedure status where db=‘test’\G
刪除
drop procedure p1;
//
儲存過程的引數
 in 輸入引數
只用來接收傳入的值

 out 輸出引數
只用來為外部變數賦值

 inout 輸入輸出引數

 定義:create procedure p1(in a int, out b int)
set b=…;
 呼叫: call p1(5, @v1);
select @v1;

流程控制
 If then - else - end if
if 條件 then
程式碼
end if;

if 條件 then
程式碼1
else
程式碼2
end if;

 case
when 條件 then ….;
when 條件 then …;
else …;
end case;

 迴圈
while 條件 do

end while;

loop

end loop;

repeat

until 條件 end repeat;

leave 跳出迴圈
iterate 直接進入下次迭代

迴圈命名
lp: loop
leave lp;
iterate lp;
end loop;

區域性變數
 declare v1 int default 0;
 區域性變數只在它定義的程式碼塊內有效
函式
 函式有返回值
 需要定義返回型別,並最終返回一個計算結果

建立函式
create function f(引數) returns int
begin

return 計算結果;
end;

檢視函式

     show create function f\G
     show function status\G
     show function status where db='test'\G

刪除函式
drop function f;

觸發器
 在新增、修改、刪除資料時,
觸發一段程式碼執行
 六個觸發時間(一個表最多6個觸發器):
before insert
before update
before delete

after insert
after update
after delete
 兩個隱含物件: new、old
 new : 新資料行
 old : 舊資料行

 insert
 new: 新插入的資料行
 old: 沒有
 update
 new: 修改之後的資料
 old: 修改之前的資料
 delete
 new: 沒有
 old: 被刪除的資料

建立觸發器
create trigger 名稱 before insert on tb1 for each row
begin

end;

檢視觸發器
use information_schema
select * from triggers\G

刪除觸發器
drop trigger 名稱;

資料庫備份和恢復
 備份
Windows命令列執行:

mysqldump -uroot -p
–default-character-set=utf8
庫名>d:\a\abc.sql

 恢復
Windows 命令列執行:(恢復的資料庫要事先存在)

mysql -uroot -p
–default-character-set=utf8
庫名< d:\a\abc.sql
練習

  1.   測試儲存過程引數
    

delimiter //
drop procedure if exists p1;
//
create procedure
p1(in a double, out b double)
begin
set @r=a*a;
select @r;
set [email protected];
end;
//

set @v1=0;
call p1(5, @v1);
//
select @v1;
//

  1.   if判斷測試
    

drop procedure if exists p2;
//
create procedure p2(in a int)
begin
if a=1 then
select ‘a的值是1’ c1;
end if;
– 此處是分割線
if a=2 then
select ‘a的值是2’ c2;
else
select ‘a的值不是2’ c3;
end if;
end;
//
call p2(1);
//
call p2(2);
//
call p2(3);
//

  1.   case測試
    

drop procedure if exists p3;
//
create procedure p3(in a int)
begin
case
when a=1 then select 100;
when a=2 then select 200;
when a=3 then select 300;
else select 10000;
end case;
end;
//
call p3(1);
call p3(2);
call p3(3);
call p3(4);
//

  1.   迴圈向表中插入1到5
    

use test;
drop table if exists tb1;
//
create table tb1(
id int primary key auto_increment,
c int
);
//
drop procedure if exists p4;
//
create procedure p4()
begin
declare i int default 0; – 定義區域性變數
– while測試
while i<5 do
set i=i+1;
insert into tb1© values(i);
end while;
– loop測試
set i=0;
lp: loop
set i=i+1;
insert into tb1© values(i);
if i=5 then
leave lp;
end if;
end loop;
– repeat迴圈
set i=0;
repeat
set i=i+1;
insert into tb1© values(i);
until i=5 end repeat;
end;
//
call p4();
//
Select * from tb1;
//

  1.   建立函式 pow(a, b) 求a的b次方
    

drop function if exists pow;
//
create function pow(a double, b int)
returns double
begin
declare r double default a;
declare i int default 0;
if b=0 then
return 1;
end if;

       while i<b-1 do
                set r=r*a;
                set i=i+1;
       end while;
       return r;

end;
//
select pow(2,3);
select pow(2,0);
select pow(3.14,3);
//

  1.   生成隨機字串,長度[n1, n2)
    

floor(5+[0,1)*5) -> 5+[0, 5)
rand()

s = ‘abcdefg’ substring(s,r,1) 提取r位置開始的1個字元
|
r

delimiter //
drop function if exists rand_str;
//
create function rand_str(n1 int, n2 int)
returns varchar(255)
begin
declare len int; – 隨機長度
declare r int; – 字串中的隨機位置
declare s0 varchar(600) default ‘abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ的一是在不了有和人這中大為上個國我以要他時來用們生到作地於出就分對成會可主發年動同工也能下過子說產種面而方後多定行學法所民得經十三之進著等部度家電力裡如水嚴龍飛’; – 一堆字元
declare s varchar(255) default ‘’; – 產生的結果
declare i int default 0; – 控制迴圈次數
– 產生一個 [n1,n2)的隨機長度
set len = floor(n1+(n2-n1)*rand());
– 迴圈 len 次
while i<len do
– 產生隨機位置1+[0,char_length(s0))
set r=floor(1+ char_length(s0)*rand());
– r位置字元拼到s
set s=concat(s, substring(s0,r,1));
set i=i+1;
end while;
return s; – 返回隨機字串
end;
//
select rand_str(2,5); //

  1.   儲存過程,迴圈插入大量資料
    
  1.   建立記憶體表
    

engine=innodb
myisam
memory 記憶體表
2) 迴圈產生資料,插入記憶體表
3) 把記憶體表資料,批量插入磁碟表

– 記憶體表
drop table if exists tm;
//
create table tm(
s varchar(255)
)engine=memory;
//
– 磁碟表
drop table if exists t;
//
create table t(
id int primary key auto_increment,
c varchar(255)
)engine=innodb;
//

                        -- 建立儲存過程用來產生大量資料插入t表
                        drop procedure if exists gen_data;
                        //
                        create procedure gen_data(in n int)
                        begin
                                 declare i int default 0;
                                 while i<n do
                                           insert into tm values(rand_str(2,5));
                                           set i=i+1;
                                 end while;
                                 insert into t(c) select s from tm;
                                 delete from tm;
                        end;
                        //
                        call gen_data(10); //
  1.   測試查詢過濾效率
    

select * from t limit 10; //
select * from t where c=‘的一’; //
select * from t where c like ‘的一%’; //
select * from t where c like ‘%的一%’; //

explain select * from t where c=‘的一’; //
explain select * from t where c like ‘的一%’; //
explain select * from t where c like ‘%的一%’; //

explain select * from t where id=3355332; //

  1.   建立 c 欄位索引,再查詢測試查詢效率
    

create index c_index on t©; //

  1. 測試觸發器,修改使用者資料時,自動修改updated欄位的時間
    use jtdb;

create trigger user_before_update_trigger
before update on tb_user for each row
begin
set new.updated=now();
end;
//
– 修改id=14使用者的密碼
update tb_user set password=md5(‘123’)
where id=14;
//
– 查詢id=14使用者,檢視修改時間是否改變
Select * from tb_user where id=14;
//

  1. 不允許刪除商品(tb_item)
    delete from tb_item where …
    直接出錯

create trigger item_before_delete_trigger
before delete
on tb_item for each row
begin
– 暴力丟擲錯誤
delete from 不允許刪除商品;
end;
//
Delete from tb_item where id=536563;
//
Select * from tb_item where id=536563;
//