MySQL存儲(chǔ)過程及語(yǔ)法詳解
1. 存儲(chǔ)過程基本用法
1.1 概念
- 存儲(chǔ)過程,也叫做存儲(chǔ)程序,是一條或者多條SQL語(yǔ)句的集合,可以視為批量處理,但是其作用不僅僅局限于批量處理。
- 其中針對(duì)存儲(chǔ)過程也有多種操作:如何創(chuàng)建存儲(chǔ)過程,以及如何調(diào)用、查看、修改、刪除存儲(chǔ)過程。存儲(chǔ)過程也可以調(diào)用其他存儲(chǔ)過程。(類似于Java函數(shù)之間的相互調(diào)用)
- 存儲(chǔ)過程和函數(shù)是:事先經(jīng)過編譯并存儲(chǔ)在數(shù)據(jù)庫(kù)中的一段SQL語(yǔ)句的集合,調(diào)用存儲(chǔ)過程和函數(shù)可以簡(jiǎn)化應(yīng)用開發(fā)人員的很多工作,減少數(shù)據(jù)庫(kù)和應(yīng)用之間的傳輸,對(duì)于提高數(shù)據(jù)處理的效率是非常有好處的。
函數(shù):是一個(gè)有返回值的過程;過程:是一個(gè)沒有返回值的函數(shù)
存儲(chǔ)過程和自定義函數(shù)的區(qū)別:
- 存儲(chǔ)過程實(shí)現(xiàn)的功能要復(fù)雜一些;而函數(shù)的針對(duì)性更強(qiáng)。
- 存儲(chǔ)過程可以返回多個(gè)值;函數(shù)只能有一個(gè)返回值。
- 存儲(chǔ)過程一般獨(dú)立的來(lái)執(zhí)行;而函數(shù)可以作為其他SQL語(yǔ)句的組成部分實(shí)現(xiàn)出來(lái)。
1.2 創(chuàng)建存儲(chǔ)過程
1.2.1 語(yǔ)法格式
# 這個(gè)地方其實(shí)是用來(lái)聲明SQL語(yǔ)句的結(jié)束符號(hào)的 delimiter // ? # 這個(gè)地方此時(shí)真正的用來(lái)創(chuàng)建一個(gè)存儲(chǔ)過程的 create procedure 存儲(chǔ)過程名稱(參數(shù)列表) begin -- sql語(yǔ)句 end// ? # 當(dāng)創(chuàng)建完一個(gè)存儲(chǔ)過程之后再將分隔符替換為分號(hào),為了不影響其他的操作 delimiter ;
2.2.2 語(yǔ)法介紹
- delimiter : 用于設(shè)置sql語(yǔ)句分割符,默認(rèn)為分號(hào)。因?yàn)樵贛ySQL中每一條SQL語(yǔ)句都必須以 ;進(jìn)行結(jié)束,當(dāng)我們換行的時(shí)候就會(huì)執(zhí)行這條SQL語(yǔ)句,但是我們此時(shí)的存儲(chǔ)過程并沒有結(jié)束,就會(huì)造成直接執(zhí)行沒有寫完的存儲(chǔ)過程造成報(bào)錯(cuò),所以此時(shí)需要聲明其他的結(jié)束符,不讓其使用默認(rèn)的分隔符結(jié)束SQL語(yǔ)句。
- sql語(yǔ)句 :在這個(gè)部分編寫sql語(yǔ)句,編寫的語(yǔ)句需要以分號(hào)結(jié)尾,此時(shí)回車會(huì)直接執(zhí)行,所以要?jiǎng)?chuàng)建存儲(chǔ)過程前需要指定其他符號(hào)作為分割符,此時(shí)使用 // , 也可以使用其它字符。
- // : 聲明結(jié)束符號(hào),這個(gè)符號(hào)可以是任意的,是自定義的。相當(dāng)于就是把 分號(hào)替換為 //
創(chuàng)建存儲(chǔ)過程查詢學(xué)生信息
# 將SQL語(yǔ)句的結(jié)束符號(hào)分隔符替換為// delimiter // ? create procedure proc_stu() begin select * from students; # 此時(shí)這個(gè)分號(hào)并不會(huì)結(jié)束這個(gè)語(yǔ)句,存儲(chǔ)過程中的SQL語(yǔ)句還是用分隔符進(jìn)行分隔 end // # 這里使用這個(gè)結(jié)束符號(hào)代表這個(gè)存儲(chǔ)過程創(chuàng)建完成 ? delimiter; # 創(chuàng)建完一個(gè)存儲(chǔ)過程之后將結(jié)束符號(hào)替換為分號(hào),防止進(jìn)行其他操作的時(shí)候有問題
1.3 調(diào)用存儲(chǔ)過程
語(yǔ)法格式:
call proc_stu(); # 調(diào)用的時(shí)候需要加上括號(hào),因?yàn)榭赡艽嬖趨?shù)
1.4 查看存儲(chǔ)過程
語(yǔ)法格式:
# 查詢 studnet 數(shù)據(jù)庫(kù)中的所有的存儲(chǔ)過程 select name from mysql.proc where db='studnet'; ? # 查詢存儲(chǔ)過程的狀態(tài)信息 show procedure status;
1.5 刪除存儲(chǔ)過程
語(yǔ)法格式:
drop procedure proc_stu; # 刪除的時(shí)候不要加小括號(hào),直接給定存儲(chǔ)過程的名字即可。 drop procedure if exists proc_stu; # 如果存儲(chǔ)刪除,不存在不刪除并且不會(huì)報(bào)錯(cuò)
2. 存儲(chǔ)過程中的語(yǔ)法結(jié)構(gòu)
- 存儲(chǔ)過程是可以編程的,意味著可以使用變量、表達(dá)式、控制語(yǔ)句來(lái)完成比較復(fù)雜的功能。
2.1 變量的聲明以及賦值
2.1.1 DECLARE 聲明變量
DECLARE : 通過 DECLARE 關(guān)鍵字可以定義一個(gè)局部變量,該變量的作用范圍只能在 BEGIN..,END 塊中。
語(yǔ)法格式:
DECLARE 變量名[,...] type [DEFAULT value]
注意:聲明變量的時(shí)候可以一次性聲明多個(gè),使用逗號(hào)隔開。
示例:
delimiter $ create procedure proc_stu() begin declare num int default 5; select num + 10; # 輸出結(jié)果為15 end $ delimiter ;
2.1.2 SET 變量賦值
SET : 直接賦值使用SET關(guān)鍵字,可以賦常量或者是表達(dá)式,具體語(yǔ)法如下:
SET 變量名 = 變量值 [,變量名 = 變量值] ...
注意:一次可以給多個(gè)變量賦值,中間使用逗號(hào)隔開。
delimiter $? create procedure proc_stu() begin declare name varchar(20); ?# 可以指定變量類型以及變量的范圍 set name = 'MySQL'; ?# 給變量直接賦值 select name; # 輸出結(jié)果為:MySQL end $ ? delimiter ;
2.1.3 select...into 賦值
delimiter $? create procedure proc_student() begin declare count_num int(10); select count(*) into count_num from student; select count_num; end $ ? delimiter ;
2.2 條件判斷
2.2.1 if條件判斷
語(yǔ)法結(jié)構(gòu):
# 只有滿足差選條件才會(huì)執(zhí)行 then 后面的SQL語(yǔ)句 if search_condition(查詢條件) then statement_list(SQL語(yǔ)句) [else if search_condition(查詢條件) then statement_list(SQL語(yǔ)句)]... [else statement_list(SQL語(yǔ)句)] end if;
需求:
根據(jù)身高,判斷當(dāng)前身高所屬的身材類型
180及以上 --------> 身材高挑
170 - 180 --------> 標(biāo)準(zhǔn)身材
170以下 ----------> 一般身材
實(shí)現(xiàn)這個(gè)簡(jiǎn)單的邏輯:
delimiter $ ?create procedure pro_figure() begin # 定義一個(gè)身高的變量 declare height int(11) default 175; # 定義一個(gè)存儲(chǔ)身高類型的變量 declare figure varchar(50) default ''; # 使用 if 語(yǔ)句判斷身材類型 if height >= 180 then set figure = '身材高挑'; else if height < 180 and height >= 170 then ? set figure = '標(biāo)準(zhǔn)身材'; ? ?else set figure = '一般身材'; ? ?end if; ? ?# 輸出結(jié)果 ? ?select concat(height + '身高的身材為:' + figure); end $ ? delimiter ;
2.3 傳遞參數(shù)
語(yǔ)法格式:
delimiter $ ? # 我們可以不指定 [in/out/inout] , 默認(rèn)為 in,輸入?yún)?shù) create procedure pro_name([in/out/inout]參數(shù)名 參數(shù)類型) begin -- sql語(yǔ)句 end $ delimiter ; # in : 該參數(shù)可以作為輸入,調(diào)用該存儲(chǔ)過程需要傳入的值,默認(rèn) # out : 該參數(shù)作為輸出,調(diào)用該存儲(chǔ)過程之后返回的值。 # inout : 既可以作為輸入?yún)?shù)也可以作為輸出參數(shù)。
2.3.1 IN - 輸入?yún)?shù)
需求:根據(jù)輸入的身高變量的值,判斷當(dāng)前身高對(duì)應(yīng)的身材類型
實(shí)現(xiàn):
delimiter $ # 此時(shí)調(diào)用者在調(diào)用這個(gè)存儲(chǔ)過程的時(shí)候必須傳遞身高的變量值 create procedure pro_name(in height int(11)) begin # 定義一個(gè)存儲(chǔ)身高類型的變量 declare figure varchar(50) default ''; # 使用 if 語(yǔ)句判斷身材類型 if height >= 180 then set figure = '身材高挑'; else if height < 180 and height >= 170 then ? set figure = '標(biāo)準(zhǔn)身材'; ? ?else set figure = '一般身材'; ? ?end if; ? ?# 輸出結(jié)果 ? ?select concat(height + '身高的身材為:' + figure); end $ ? delimiter ;
調(diào)用:
# 調(diào)用該存儲(chǔ)過程。需要傳遞其中的身高值 call pro_name(175); ?# 輸出結(jié)果為:
2.3.2 out - 輸出參數(shù)
需求:根據(jù)輸入的身高,返回當(dāng)前身高所處的身材類型
實(shí)現(xiàn):
delimiter $? create procedure pro_output(in height int(11) , out figure varchar(100)) begin # 使用 if 語(yǔ)句判斷身材類型 if height >= 180 then set figure = '身材高挑'; else if height < 180 and height >= 170 then ? set figure = '標(biāo)準(zhǔn)身材'; ? ?else set figure = '一般身材'; ? ?end if; end $ delimiter ;
調(diào)用:
# @標(biāo)識(shí)符:在MySQL中代表的就是用戶定義的一個(gè)變量,這里我們使用這個(gè)變量來(lái)接收這個(gè)存儲(chǔ)過程的返回值 call pro_output(175 , @figure); ? # 查看存儲(chǔ)過程返回的結(jié)果 select @figure;
@標(biāo)識(shí)符的作用
- @figure :這種在變量名前面加上”@“符號(hào),叫做用戶會(huì)話變量,代表整個(gè)會(huì)話過程他都是有作用的,這個(gè)類似于全局變量一樣。當(dāng)前會(huì)話就是代表的,比如我們?cè)诿钐崾敬翱谥薪o好多帶有 @ 符號(hào)變量進(jìn)行賦值,此時(shí)這些變量的值只作用于當(dāng)前的會(huì)話,當(dāng)我們把這個(gè)窗口關(guān)閉的時(shí)候,此時(shí)這些變量的值就會(huì)釋放掉。
- @@global : 這種在變量名前加上 "@@" 符號(hào),叫做系統(tǒng)變量。
2.4 case 結(jié)構(gòu)
語(yǔ)法格式:
# 方式一 case case_value(判斷的值) when when_value(比較的值) then statement_list(SQL語(yǔ)句) [when when_value(比較的值) then statement_list(SQL語(yǔ)句)]... [else statement_list(SQL語(yǔ)句)] end case; ? # 方式二 case when search_condition(查詢條件) then statement_list(SQL語(yǔ)句) [when search_condition(查詢條件) then statement_list(SQL語(yǔ)句)]... [else statement_list(SQL語(yǔ)句)] end case;
需求:給定一個(gè)月份,判斷該月份所屬的季度
實(shí)現(xiàn):
delimiter $? create procedure pro_quarter(in mon int(11)) begin # 定義存儲(chǔ)季度的變量 declare result varchar(10); case when mon >= 1 and mon <= 3 then set result = '第一季度'; when mon >= 4 and mon <= 6 then set result = '第一季度'; when mon >= 7 and mon <= 9 then set result = '第一季度'; else set result = '第四季度'; ? ? ? ?end case; # 輸出結(jié)果 select result; end $ ? delimiter ;
2.5 while循環(huán)
有條件的循環(huán)控制語(yǔ)句,當(dāng)滿足條件的時(shí)候進(jìn)入循環(huán),不滿足條件的時(shí)候退出循環(huán)。
語(yǔ)法結(jié)構(gòu):
# 只要查詢條件一直成立就會(huì)一直指定do后面的SQL語(yǔ)句,當(dāng)查詢條件不成立的時(shí)候直接跳出while循環(huán) while search_condition(查詢條件) do statement_list(SQL語(yǔ)句) end while;
需求:計(jì)算從1加到n的值
實(shí)現(xiàn):
delimiter $? create procedure pro_sum(in num int(11)) begin # 定義存儲(chǔ)總數(shù)的變量 declare total int(255) default 0; # 定義存儲(chǔ)循環(huán)次數(shù)的數(shù)量 declare number int(255) default 1; while number <= num do set total = total + number; set number = number + 1; end while; select total; end $ ? delimiter ;
2.6 repeat循環(huán)
有條件的循環(huán)控制語(yǔ)句,當(dāng)不滿足條件的時(shí)候進(jìn)入循環(huán),滿足條件的時(shí)候跳出循環(huán)。他和while循環(huán)是反著的
語(yǔ)法結(jié)構(gòu):
repeat statement_list(SQL語(yǔ)句) until search_condition(查詢添加) end repeat;
需求:計(jì)算從1加到n的值
實(shí)現(xiàn):
delimiter $? create procedure pro_sum(in num int(11)) begin # 定義存儲(chǔ)總數(shù)的變量 declare total int(255) default 0; repeat set total = total + number; set num = num - 1; # 注意:這個(gè) unti 后的查詢條件不要加分號(hào),加分號(hào)會(huì)報(bào)錯(cuò)。 until num = 0 end repeat; select total; end $ ? delimiter ;
2.7 loop循環(huán)
loop實(shí)現(xiàn)簡(jiǎn)單的循環(huán),退出循環(huán)的條件需要使用其他的語(yǔ)句定義,通??梢允褂胠eave語(yǔ)句實(shí)現(xiàn),具體語(yǔ)法如下:
語(yǔ)法格式:
[begin_label:] loop statement_list end loop [end_label]
如果不在statement_list中增加退出循環(huán)的語(yǔ)句,那么loop語(yǔ)句可以永安里實(shí)現(xiàn)簡(jiǎn)單的死循環(huán)。
2.8 leave語(yǔ)句
用來(lái)從標(biāo)注的流程構(gòu)造中退出,通常和 begin...end 或循環(huán)一起使用。下面是一個(gè)使用loop和leave的簡(jiǎn)單例子,退出循環(huán):
需求:計(jì)算從1加到n的值 ---> 使用loop...leave的形式進(jìn)行退出循環(huán)
實(shí)現(xiàn):
delimiter $ create procedure pro_sum(in num int(11)) begin # 定義存儲(chǔ)總數(shù)的變量 declare total int(255) default 0; c(該循環(huán)的別名):loop set total = total + num; set num = num - 1; # 借助leave組織退出條件 if num <= 0 then ? ? ? leave c; ? ? ? ?end if; end loop c; select total; end $ delimiter ;
到此這篇關(guān)于MySQL存儲(chǔ)過程及語(yǔ)法詳解的文章就介紹到這了,更多相關(guān)MySQL存儲(chǔ)語(yǔ)法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Mysql?InnoDB聚簇索引二級(jí)索引聯(lián)合索引特點(diǎn)
這篇文章主要為大家介紹了Mysql?InnoDB聚簇索引二級(jí)索引聯(lián)合索引特點(diǎn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05分享幾個(gè)簡(jiǎn)單MySQL優(yōu)化小妙招
這篇文章主要介紹了分享幾個(gè)簡(jiǎn)單MySQL優(yōu)化小妙招,分享內(nèi)容有、設(shè)置大小寫不敏感、MySql?的用戶和權(quán)限管理等內(nèi)容,需要的小伙伴可以參考一下,需要的朋友可以參考下2022-03-03優(yōu)化mysql數(shù)據(jù)庫(kù)的經(jīng)驗(yàn)總結(jié)
本篇文章是對(duì)優(yōu)化mysql數(shù)據(jù)庫(kù)的經(jīng)驗(yàn)進(jìn)行了詳細(xì)的總結(jié)介紹,需要的朋友參考下2013-06-06