介紹
基本語法
創建
調用
查看
刪除
變量
系統變量
查看
設置
用戶定義變量
賦值
使用
局部變量
聲明
賦值
流程控制
參數
條件結構
IF
case
循環結構
while
repeat
loop
游標
條件處理程序
介紹
舉個簡單的例子,我們先select某數據,然后update,再update。這一系列操作指令是在MySQL中
下達的,然后指令傳輸到應用層,那么導致的問題就是,多次的指令傳輸會涉及到網絡的請求。
所以存儲過程就是,由一系列SQL語句經過編譯后的指令集合,通過調用這個集合可以簡化開發者的流程。最重要的是,能夠減少數據在數據庫和應用服務器之間的傳輸,提高數據處理的效率。
儲存過程的思想很簡單,就是在SQL語言層面的代碼的封裝和重用。
存儲過程的特點:
- 封裝、復用
- 可以接受參數、也可以返回數據
- 減少網絡層的交互,提升效率
基本語法
創建
create procedure p1() --存儲過程名稱,也可以添加參數
begin--具體的SQL語句
end;
調用
call p1();
查看
- 通過MySQL系統中的信息查看
select *from information_schema.ROUTINES where ROUTINE_SCHEMA = 'text';
--數據庫名
- 查看創建語句
show create procedure p1;
刪除
drop procedure [if exist] p1;
注意!!!如果使用命令行執行存儲過程的創建語句,會報錯:
這是因為,在命令行中以分號為一句命令的結束,所以會導致報錯。
所以在命令行中執行創建語句時,應該使用delimiter關鍵字指定命令結束符:
delimiter $$ --指定兩個美元符號為結束符號create procedure p1() --存儲過程名稱,也可以添加參數
begin-----;
end;$$
變量
-
系統變量
系統變量是MySQL服務器指定的,不是用戶定義的,屬于服務器層面,Global(全局變量)、Session(會話變量,只代表當前會話)
查看
show variables;
--show global variables;
--show session variables;show variables like 'ac%';
--模糊匹配select @@activate_all_roles_on_login;
--查找指定的系統變量名
設置
set session 系統變量名 = 值;
--set global 系統變量名 = 值;
注意:
- 當沒有指定global和session時,系統默認是session會話變量
- 當mysql重啟時沒所有設置的全局參數將會失效,要想不失效,可以在配置文件中配置
-
用戶定義變量
賦值
set @myname = 'John';
set @myage := 10;
--相當于定義了兩個變量,并且賦值set @mynumber = 12345 , @myaddress = '北京市';
--可以同時定義兩個用戶變量select set @mycolor := '中國紅';
--可以使用select進行賦值select count(*) into @mynum from users;
--可以使用其他表的字段來進行賦值
使用
select @mycolor,@myage;
-
局部變量
聲明
declare user_num int;
--user_num是局部變量名
賦值
與用戶自定義變量賦值相似
流程控制
參數
create procedure p2(in score int,out ret varchar(10))
beginif score >=15 thenset ret = '優秀';elseset ret = '及格';end if;
end;call p2(18,@ret);
select @ret;
運行結果:
條件結構
-
IF
create procedure p2()
begindeclare score int default 20;declare ret varchar(10);if score >=15 thenset ret = '優秀';elseset ret = '及格';end if;select ret;
end;call p2();
還是比較好理解的,類似于編程語言中的IF語句。
-
case
create procedure p3(in month int)
begindeclare ret varchar(10);casewhen month>=1 and month<=3 thenset ret := '第一季度';when month>=4 and month<=6 thenset ret := '第二季度';when month>=7 and month<=9 thenset ret := '第三季度';when month>=10 and month<=12 thenset ret := '第四季度';else set ret := '非法參數';end case;select concat('您輸入的月份為:',month,' 所屬季度為:',ret);
end;call p3(12);
循環結構
-
while
WHILE? ?條件? ?DO
? ? ? ? SQL邏輯語句
END WHILE;
演示
輸入一個參數n,返回從1到n的累加
create procedure p4(in n int)
begindeclare total int default 0;while n>=1 doset total = total + n;set n = n - 1;end while;select total;
end;call p4(10);
運行結果
-
repeat
滿足條件退出循環
repeat
? ? ? ? SQL邏輯語句
UNTIL? ?條件
end? ?repeat;
-
loop
?loop一般配合下面兩個語句使用:
- LEAVE(直接退出循環)
- ITERATE(跳過本次循環的剩下語句,然后進入下一次循環)
create procedure p4(in n int)
begindeclare total int default 0;sum loop:if n<=0 thenleave;end if;set total = total + n;set n = n - 1;end loop sum;select total;
end;call p4(10);
游標
游標是用來存儲查詢數據集的數據類型,在存儲過程或函數過程中對結果集進行循環的處理。
- 聲明游標
declare? 游標名? cursor? 查詢結果集;
--輸入年齡上限,將所有小于該年齡的數據的部分字段,作為一個游標create procedure p5(in n int)
begindeclare uname varchar(10);declare ugender varchar(10);declare u_cursor cursor for select user_name,user_gender from users where user_age<=n;drop table if exists u_name_gen;create table if not exists u_name_gen(id int primary key auto_increment,name varchar(10),gender varchar(10));open u_cursor;while true dofetch u_cursor into uname,ugender;insert into u_name_gen values (null,uname,ugender);end while;close u_cursor;end;call p5(32);
這里要注意的是,表確實創建成功了,但是MySQL依然會報錯:
這里的原因在于存儲過程中的循環沒有有效的停止。?
條件處理程序
條件處理程序用于在存儲過程中拋出異常時,解決問題的相應步驟。