一、存儲(chǔ)過程是什么
?? 存儲(chǔ)過程是事先經(jīng)過編譯并存儲(chǔ)在數(shù)據(jù)庫中的 SQL 語句的集合,調(diào)用存儲(chǔ)過程可以簡(jiǎn)化應(yīng)用開發(fā)人員的很多工作,減少數(shù)據(jù)在數(shù)據(jù)庫和應(yīng)用服務(wù)器之間的傳輸,可以提高數(shù)據(jù)處理效率
?? 存儲(chǔ)過程思想上很簡(jiǎn)單:就是數(shù)據(jù)庫 SQL 語言層面的代碼封裝與重用
?? 【封裝,復(fù)用】可以把某一業(yè)務(wù)的 SQL 封裝在存儲(chǔ)過程中,需要用到的時(shí)候直接調(diào)用存儲(chǔ)過程
?? 可以接收參數(shù),也可以返回?cái)?shù)據(jù)
?? 【減少網(wǎng)絡(luò)交互,效率提升】如果涉及到多條 SQL,每執(zhí)行一次都是一次網(wǎng)絡(luò)傳輸。 而如果封裝在存儲(chǔ)過程中,只需要網(wǎng)絡(luò)交互一次就可以了
二、存儲(chǔ)過程的基本語法
# 創(chuàng)建存儲(chǔ)過程
CREATE PROCEDURE p ( ) BEGIN
SELECT
count( * ) '學(xué)生數(shù)量'
FROM
student;
END;
# 執(zhí)行存儲(chǔ)過程
CALL p();
# 刪除存儲(chǔ)過程
DROP PROCEDURE IF EXISTS p;
三、MySQL 中的變量
MySQL 中的變量分為三種: 系統(tǒng)變量、用戶定義變量、局部變量
(1) 系統(tǒng)變量
系統(tǒng)變量是 MySQL 服務(wù)器提供的,屬于服務(wù)器層面。分為全局變量(GLOBAL)、會(huì)話變量(SESSION)
# 查看系統(tǒng)變量
show variables;
show session variables;
show global variables;
show global variables like 'auto%';
select @@autocommit;
select @@global.autocommit;
select @@session.autocommit;
set session autocommit = 0;
set @@session.autocommit = 1;
(2) 用戶自定義變量
- 用戶定義變量:是用戶自己定義的變量,用戶變量不用提前聲明
- 賦值的時(shí)候直接用
@變量名
就可以。 - 其作用域?yàn)楫?dāng)前連接
賦值方式1:
set @my_name = '張國慶';
set @my_age = 3;
set @my_gender = 'boy', @my_hobby = 'sleep';
# 查看變量
select @my_name, @my_age, @my_gender, @my_hobby;
賦值方式2:
select @money := 16685206840;
select @money '張國慶的銀行卡余額';
賦值方式3:
select count(*) into @student_num from student;
select @student_num '學(xué)生數(shù)量';
注意: 用戶定義的變量無需對(duì)其進(jìn)行聲明或初始化,只不過獲取到的值為NULL。
(3) 局部變量
??局部變量是用戶自定義的在局部生效的變量
??訪問之前,需要 DECLARE
聲明
?? 可用作存儲(chǔ)過程內(nèi)的局部變量和輸入?yún)?shù)
?? 局部變量的范圍在聲明的 BEGIN ... END
塊內(nèi)
# 創(chuàng)建存儲(chǔ)過程
create procedure p_test1 ()
begin
declare stu_num int default 0;
select count(*) into stu_num from student;
select stu_num '學(xué)生人數(shù)';
end;
# 調(diào)用存儲(chǔ)過程
call p_test1();
四、if 判斷
根據(jù)定義的分?jǐn)?shù) score 變量,判定當(dāng)前分?jǐn)?shù)對(duì)應(yīng)的分?jǐn)?shù)等級(jí):
?? score >= 85分,等級(jí)為優(yōu)秀
?? score >= 60分 且 score < 85分,等級(jí)為及格
?? score < 60分,等級(jí)為不及格
create procedure p100()
begin
declare score int default 66;
declare result char(3);
if score > 85 then
set result := '優(yōu)秀';
elseif score > 60 then
set result := '及格';
else
set result := '不及格';
end if;
select result '分?jǐn)?shù)等級(jí)';
end;
# 調(diào)用
call p100();
五、參數(shù)傳遞和返回值
根據(jù)傳入參數(shù) score,判定當(dāng)前分?jǐn)?shù)對(duì)應(yīng)的分?jǐn)?shù)等級(jí),并返回:
?? score >= 85分,等級(jí)為優(yōu)秀
?? score >= 60分 且 score < 85分,等級(jí)為及格
?? score < 60分,等級(jí)為不及格
create procedure p101(in score int, out result char(3))
begin
if score > 85 then
set result := '優(yōu)秀';
elseif score > 60 then
set result := '及格';
else
set result := '不及格';
end if;
end;
# 調(diào)用
call p101(58, @result);
# 查看返回值
select @result 'result';
?? 將傳入的 200 分制的分?jǐn)?shù)換算成百分制,然后返回。
create procedure p102(inout score double)
begin
# set score = score * 0.5;
set score = score >> 1;
end;
# 調(diào)用
set @param_result = 78;
call p102(@param_result);
# 查看返回值
select @param_result 'score';
六、case 語句
根據(jù)傳入的月份,判定月份所屬的季節(jié)(要求采用 case 結(jié)構(gòu))。
?? 1-3月份,為第一季度
?? 4-6月份,為第二季度
?? 7-9月份,為第三季度
?? 10-12月份,為第四季度
create procedure p103(in `month` int)
begin
declare result char(4);
case
when month between 1 and 3 then set result := '第一季度';
when month <= 4 and month >= 6 then set result := '第二季度';
when month between 7 and 9 then set result := '第三季度';
when month between 10 and 12 then set result := '第四季度';
else set result = '非法參數(shù)';
end case;
select concat(`month`, '月份是', result) 'result';
end;
# 調(diào)用
call p103(09);
七、while 循環(huán)
?? 計(jì)算從1累加到 n 的值,n 為傳入的參數(shù)值
create procedure p104(in n int)
begin
declare sum int default 0;
while n > 0 do
set sum := sum + n;
set n := n - 1;
end while;
select sum;
end;
# 調(diào)用
call p104(100);
八、repeat 循環(huán)
?? 計(jì)算從1累加到 n 的值,n 為傳入的參數(shù)值
create procedure p105(in n int)
begin
declare sum int default 0;
repeat
set sum := sum + n;
set n = n -1;
until n <= 0
end repeat;
select sum;
end;
# 調(diào)用
call p105(10);
九、loop 循環(huán)
LOOP 實(shí)現(xiàn)簡(jiǎn)單的循環(huán),如果不在SQL邏輯中增加退出循環(huán)的條件,可以用其來實(shí)現(xiàn)簡(jiǎn)單的死循環(huán)。
LOOP 可以配合以下兩個(gè)語句使用:
?? LEAVE :配合循環(huán)使用,退出循環(huán)。
?? ITERATE:必須用在循環(huán)中,作用是跳過當(dāng)前循環(huán)剩下的語句,直接進(jìn)入下一次循環(huán)。
?? 計(jì)算從1累加到 n 的值,n 為傳入的參數(shù)值
create procedure p106(in n int)
begin
declare sum int default 0;
flag:loop
if n <= 0 then
leave flag;
end if;
set sum := sum + n;
set n := n - 1;
end loop flag;
select sum;
end;
# 調(diào)用
call p106(10);
十、游標(biāo)
- 游標(biāo)(CURSOR)是用來存儲(chǔ)查詢結(jié)果集的數(shù)據(jù)類型 , 在存儲(chǔ)過程和函數(shù)中可以使用游標(biāo)對(duì)結(jié)果集進(jìn)行循環(huán)的處理
- 游標(biāo)的使用包括游標(biāo)的聲明、OPEN、FETCH 和 CLOSE
?? 根據(jù)傳入的參數(shù) uage
,查詢用戶表 tb_user
中,所有的用戶年齡小于等于 uage
的用戶姓名(name)和專業(yè)(profession),并將用戶的姓名和專業(yè)插入到新創(chuàng)建的一張新表 (id,name,profession)
中。
select * from tb_age_name_pro;
create procedure p_cursor(in uage int)
begin
# 局部變量聲明必須在游標(biāo)聲明之前
declare uname varchar(100);
declare uprofession varchar(100);
# 定義游標(biāo)(用于存儲(chǔ)結(jié)果集)
declare age_name_pro_cursor cursor for select `name`, profession from tb_user where age <= uage;
# 創(chuàng)建表
drop table if exists tb_age_name_pro;
create table if not exists tb_age_name_pro (
id int primary key auto_increment,
uname varchar(100),
uprofession varchar(100)
);
# 游標(biāo)操作
open age_name_pro_cursor; # 打開游標(biāo)
# 循環(huán)獲取游標(biāo)記錄
while true do # 死循環(huán)
fetch age_name_pro_cursor into uname, uprofession;
# 把獲取到的數(shù)據(jù)插入到表中
insert into tb_age_name_pro values (null, uname, uprofession);
end while;
# 關(guān)閉游標(biāo)
close age_name_pro_cursor;
end;
call p_cursor(18);
十一、條件處理程序
- 條件處理程序(Handler)可以用來定義在流程控制結(jié)構(gòu)執(zhí)行過程中遇到問題時(shí)相應(yīng)的處理步驟
create procedure p_cursor(in uage int)
begin
# 局部變量聲明必須在游標(biāo)聲明之前
declare uname varchar(100);
declare uprofession varchar(100);
declare uuage varchar(3);
# 定義游標(biāo)(用于存儲(chǔ)結(jié)果集)
declare age_name_pro_cursor cursor for select age, `name`, profession from tb_user where age <= uage;
# 創(chuàng)建條件處理程序
# (1) 當(dāng) SQL 狀態(tài)碼是 02000 的時(shí)候觸發(fā)該條件處理程序, 觸發(fā)該程序后:① 關(guān)閉游標(biāo);② 終止當(dāng)前程序
# declare exit handler for sqlstate '02000' close age_name_pro_cursor;
declare exit handler for not found close age_name_pro_cursor;
# 創(chuàng)建表
drop table if exists tb_age_name_pro;
create table if not exists tb_age_name_pro (
id int primary key auto_increment,
uuage varchar(3),
uname varchar(100),
uprofession varchar(100)
);
# 游標(biāo)操作
open age_name_pro_cursor; # 打開游標(biāo)
# 循環(huán)獲取游標(biāo)記錄
while true do
fetch age_name_pro_cursor into uuage, uname, uprofession;
# 把獲取到的數(shù)據(jù)插入到表中
insert into tb_age_name_pro values (null, uuage, uname, uprofession);
end while;
# 關(guān)閉游標(biāo)
close age_name_pro_cursor;
end;
# 調(diào)用存儲(chǔ)過程
call p_cursor(22);
https://dev.mysql.com/doc/refman/8.0/en/declare-handler.html文章來源:http://www.zghlxwxcb.cn/news/detail-478875.html
https://dev.mysql.com/doc/mysql-errors/8.0/en/server-error-reference.html文章來源地址http://www.zghlxwxcb.cn/news/detail-478875.html
到了這里,關(guān)于【MySQL 數(shù)據(jù)庫】9、存儲(chǔ)過程的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!