mysql 扩展存储过程_MySQL4:存储过程和函数
什么是存儲過程
簡單說,存儲過程就是一條或多條SQL語句的集合,可視為批文件,但是起作用不僅限于批處理。本文主要講解如何創(chuàng)建存儲過程和存儲函數(shù)以及變量的使用,如何調(diào)用、查看、修改、刪除存儲過程和存儲函數(shù)等。使用的數(shù)據(jù)庫和表還是之前寫JDBC用的數(shù)據(jù)庫和表:
create database school;
use school;
create table student
(
studentId int primary key auto_increment not null,
studentName varchar(10) not null,
studentAge int,
studentPhone varchar(15)
)
insert into student values(null,'Betty', '20', '00000000');
insert into student values(null,'Jerry', '18', '11111111');
insert into student values(null,'Betty', '21', '22222222');
insert into student values(null,'Steve', '27', '33333333');
insert into student values(null,'James', '22', '44444444');
commit;
存儲程序可以分為存儲過程和函數(shù),MySQL中創(chuàng)建存儲過程和函數(shù)的語句分別是:CREATE PROCEDURE和CREATE FUNCTION。使用CALL語句來調(diào)用存儲過程,只能用輸出變量返回值。函數(shù)可以從語句外調(diào)用(即通過引用函數(shù)名),也能返回標(biāo)量值。存儲過程也可以調(diào)用其他存儲過程。
創(chuàng)建存儲過程
創(chuàng)建存儲過程,需要使用CREATE PROCEDURE語句,語句基本格式如下:
CREATE PROCEDURE sp_name([proc_parameter])
[characteristics ...] routine_body
解釋一下:
1、CREATE PROCEDURE為創(chuàng)建存儲過程的關(guān)鍵字
2、sp_name為存儲過程的名字
3、proc_parameter為指定存儲過程的參數(shù)列表,列表形式為[IN|OUT|INOUT] param_name type。其中,IN表示輸入?yún)?shù),OUT表示輸出參數(shù),INOUT表示既可以輸入也可以輸出,param_name表示參數(shù)名稱,type表示參數(shù)類型,該類型可以是MySQL數(shù)據(jù)庫中的任意類型
4、characteristics指定存儲過程的特性
5、routime_body是SQL代碼的內(nèi)容,可以用BEGIN...END來表示SQL代碼的開始和結(jié)束
編寫存儲過程不是簡單的事情,可能存儲過程中需要復(fù)雜的SQL語句,并且要有創(chuàng)建存儲過程的權(quán)限;但是使用存儲過程將簡化操作,減少冗余的操作步驟,同時還可以減少操作過程中的事物,提高效率,因此存儲過程是非常有用的。下面看兩個存儲過程,一個查詢student表中的所有字段,一個根據(jù)student表的Age字段算一個Age的平均值:
CREATE PROCEDURE proc ()
BEGIN
SELECT * FROM student;
END;
CREATE PROCEDURE AvgStudentAge()
BEGIN
SELECT AVG(studentAge) AS avgAge FROM student;
END;
上面都是不帶參數(shù)的存儲過程,下面看一個帶參數(shù)的存儲過程:
DELIMITER //
CREATE PROCEDURE CountStudent(IN sName VARCHAR(10), OUT num INT)
BEGIN
SELECT COUNT(*) INTO num FROM student WHERE studentName = sName;
END //
上述代碼的作用是創(chuàng)建一個獲取student表記錄條數(shù)的存儲過程,名稱為CountStudent,根據(jù)傳入的學(xué)生姓名COUNT(*)后把結(jié)果放入?yún)?shù)num中。
注意另外一個細(xì)節(jié),上述代碼第一行使用了"DELIMITER //",這句語句的作用是把MySQL的結(jié)束符設(shè)置為"//",因為MySQL默認(rèn)的語句結(jié)束符號為分號";",為了避免與存儲過程中SQL語句結(jié)束符相沖突,需要使用DELIMITER改變存儲過程的結(jié)束符,并以"END //"結(jié)束存儲過程。存過程定義完畢之后再使用"DELIMITER ;"恢復(fù)默認(rèn)結(jié)束符。DELIMITER也可以指定其他符號作為結(jié)束符。
創(chuàng)建存儲函數(shù)
創(chuàng)建存儲函數(shù)需要使用CREATE FUNCATION語句,其基本語法如下:
CREATE FUNCTION func_name([func_parameter]) RETURNS type
[characteristic ...] routine_body
解釋一下:
1、CREATE_FUNCTION為用來創(chuàng)建存儲函數(shù)的關(guān)鍵字
2、func_name表示存儲函數(shù)的名稱
3、func_parameter為存儲過程的參數(shù)列表,參數(shù)列表形式為[IN|OUT|INOUT] param_name type,和存儲過程一樣
4、RETURNS type表示函數(shù)返回數(shù)據(jù)的類型
5、characteristic表示存儲函數(shù)的特性,和存儲過程一樣
舉個例子:
CREATE FUNCTION NameByZip() RETURNS CHAR(50)
RETURN (select studentPhone from student where studentName = 'JAMES');
提兩點:
1、如果在存儲函數(shù)中的RETURN語句返回一個類型不同于函數(shù)的RETURNS自居指定的類型的值,返回值將被強(qiáng)制為恰當(dāng)?shù)念愋?/p>
2、指定參數(shù)為IN、OUT或INOUT只對PROCEDURE是合法的(FUNCTION中總是默認(rèn)為IN參數(shù))。RETURNS子句只能對FUNCTION做指定,對于函數(shù)而言這是強(qiáng)制性的,它用來指定函數(shù)的返回類型,而且函數(shù)體必須包含一個RETURN value語句
變量的使用
變量可以在子程序中聲明并使用,這些變量的作用范圍是在BEGIN...END程序中,在存儲過程中可以使用DECLARE語句定義變量,語法如下:
DECLARE var_name[,varame]... date_type [DEFAULT value]
解釋一下:
1、var_name為局部變量的名稱
2、DEFAULT value子句給變量提供一個默認(rèn)值,值除了可以被聲明為一個常數(shù)之外,還可以被指定為一個表達(dá)式。如果沒有DEFAULT子句,那么初始值為NULL
定義變量后,為變量賦值可以改變變量的默認(rèn)值,MySQL使用SET為變量賦值:
SET var_name=expr[, var_name=expr] ...;
舉個例子:
DECLARE var1 INT DEFAULT 100;
DECLARE var2, var3, var4 INT;
SET var2 = 10, var3 = 20;
SET var4 = var2 + var3;
當(dāng)然,我們使用SELECT語句也可以給變量賦值:
DECLARE t_studentName CHAR(20);
DECLARE t_studentAge INT;
SELECT studentName, studentId INTO t_studentName, t_studentAge FROM student where studentName = 'Bruce';DECLARE t_studentName CHAR(20);
DECLARE t_studentAge INT;
游標(biāo)的使用
查詢語句可能返回多條記錄,如果數(shù)據(jù)量非常大,需要在存儲過程和存儲函數(shù)中使用游標(biāo)來逐條讀取查詢結(jié)果集中的記錄。應(yīng)用程序可以根據(jù)需要滾動或瀏覽器中的程序。
游標(biāo)必須在處理程序之前被聲明,并且變量和條件還必須在聲明游標(biāo)或處理程序之前被聲明。MySQL中聲明游標(biāo)的方法為:
DECLARE cursor_name CURSOR FOR select_statement
解釋一下:
1、cursor_name表示游標(biāo)的名稱
2、select_statement表示SELECT語句返回的內(nèi)容,返回一個用于創(chuàng)建游標(biāo)的結(jié)果集
定義了游標(biāo),就要打開游標(biāo),打開游標(biāo)的方法為:
OPEN cursor_name{游標(biāo)名稱}
再就是使用游標(biāo)了,使用游標(biāo)的方法為:
FETCH cursor_name INTO var_name [, var_name] ... {參數(shù)名稱}
最后游標(biāo)使用完了,要關(guān)閉:
CLOSE cursor_name{游標(biāo)名稱}
舉個例子:
DECLARE t_studentName CHAR(20);
DECLARE t_studentAge INT;
DECLARE cur_student CURSOR FOR SELECT studentName, studentId FROM student where studentName = 'Bruce';
OPEN cur_student;
FETCH cur_student INTO t_studentName, t_studentAge;
...
CLOSE cur_student;
studentName為Bruce的在數(shù)據(jù)里面不止一條記錄,創(chuàng)建游標(biāo)之后就從student表中查出了studentName和studentId的值。OPEN這個游標(biāo),通過FETCH之后遍歷每一組studentName和studentAge,并放入申明的變量t_studentName和t_studentAge中,之后想怎么用這兩個字段怎么用這兩個字段了。注意,游標(biāo)用完關(guān)閉掉。
IF、CASE、LOOP、LEAVE、ITERATE、REPEAT
這六個比較簡單,放在一起講了,簡單說下用法,除了第一個IF寫個例子以外,別的就不寫例子了,可以自己嘗試下。
1、IF
IF語句包含多個判斷條件,根據(jù)判斷的結(jié)果為TRUE或FALSE執(zhí)行相應(yīng)的語句,其格式為:
IF expr_condition THEN statement_list
[ELSEIF expr_condition THEN statement_list]
[ELSE statement_list]
END IF
比如:
IF t_studentName IS NULL
THEN SELECT studentName INTO t_studentName FROM student where studentName = 'Bruce';
ELSE UPDATE studentName set student = NULL where studentName = 'Bruce';
END IF;
2、CASE
case是另外一個進(jìn)行條件判斷的語句,該語句有兩種格式,第一種格式如下:
CASE case_expr
WHEN when_value THEN statement_list
[WHEN when_value THEN statement_list] ...
[ELSE statement_list]
END CASE
其中,case_expr參數(shù)表示判斷的表達(dá)式,決定了哪一個WHEN自居會被執(zhí)行;when_value表示表達(dá)式可能的值,如果某個when_value表達(dá)式與case_expr表達(dá)式結(jié)果相同,則執(zhí)行對應(yīng)THEN關(guān)鍵字后的statement_list中的語句;statement_list參數(shù)表示不同when_value值的執(zhí)行語句。
CASE語句的第二種格式為:
CASE
WHEN expr_condition THEN statement_list
[WHEN expr_condition THEN statement_list] ...
[ElSE statement_list]
END CASE
只是寫法稍微變了一下,參數(shù)還是第一種寫法的意思
3、LOOP
LOOP循環(huán)用來重復(fù)執(zhí)行某些語句,與IF和CASE相比,LOOP只是創(chuàng)建一個循環(huán)操作的過程,并不進(jìn)行條件判斷。LOOP內(nèi)的語句一直被重復(fù)執(zhí)行直到循環(huán)被退出,跳出循環(huán)過程,使用LEAVE子句。LOOP語句j的基本格式如下:
[loop_label:] LOOP
statement_list
END LOOP
其中l(wèi)oop_label表示LOOP語句的標(biāo)注名稱,該參數(shù)可以省略;statement_list參數(shù)表示需要循環(huán)執(zhí)行的語句
4、LEAVE
LEAVE語句用來退出任何被標(biāo)注的流程控制構(gòu)造,LEAVE語句的基本格式如下:
LEAVE label
5、ITERATE
ITERATE語句將執(zhí)行順序轉(zhuǎn)到語句段開頭出,語句基本格式如下:
ITERATE label
6、REPEAT
REPEAT語句用來創(chuàng)建一個帶有條件判斷的循環(huán)過程,每次與局執(zhí)行完畢之后,會對條件表達(dá)式進(jìn)行判斷,如果表達(dá)式為真,則循環(huán)結(jié)束,否則重復(fù)執(zhí)行循環(huán)中的語句。REPEAT語句的基本格式如下:
[repeat_label:] REPEAT
statement_list
UNTIL expr_condition
END REPEAT
其中,repeat_label為REPEAT語句的標(biāo)注名稱,該參數(shù)可以省略;REPEAT語句內(nèi)的語句或語句群被重復(fù),直至expr_condition為真
調(diào)用存儲過程和函數(shù)
存儲過程已經(jīng)定義好了,接下來無非就是調(diào)用。存儲過程和函數(shù)有很多種調(diào)用方法,存儲過程必須使用CALL語句調(diào)用,并且存儲過程和數(shù)據(jù)庫相關(guān),如果要執(zhí)行其他數(shù)據(jù)庫中的存儲過程,需要指定數(shù)據(jù)庫名稱,例如CALL dbname.procname。存儲函數(shù)的調(diào)用與MySQL中預(yù)定義的函數(shù)調(diào)用方式相同。
1、調(diào)用存儲過程
存儲過程是通過CALL語句進(jìn)行調(diào)用的,語法如下:
CALL sp_name([parameter[,...]])
舉個例子,就調(diào)用最前面那個CountStudent的存儲過程:
CALL CountStudent('Bruce', @num);
select @num;
運行結(jié)果為:
2、調(diào)用存儲函數(shù)
MySQL中調(diào)用存儲函數(shù)的使用方法和MySQL內(nèi)部函數(shù)的使用方法是一樣的,無非存儲函數(shù)是用戶自己定義的,內(nèi)部函數(shù)是MySQL開發(fā)者定義的。
我們調(diào)用一下上面定義的NameByZip那個函數(shù):
select NameByZip();
運行結(jié)果為:
可以對照一下,studenName為"James"這一條,對應(yīng)的studentPhone就是"44444444",符合SELECT出來的結(jié)果
查看、刪除存儲過程和函數(shù)
1、查看存儲過程和函數(shù)的狀態(tài)
SHOW STATUS可以查看存儲過程核函數(shù)的狀態(tài),其基本語法結(jié)構(gòu)如下:
SHOW {PROCEDURE | FUNCTIOn} STATUS [LIKE 'pattern'
這個語句是一個MySQL的擴(kuò)展,他返回子程序的特征,如數(shù)據(jù)庫、名字、類型、創(chuàng)建者及創(chuàng)建和修改日期。如果沒有指定樣式,根據(jù)使用的語句,所有存儲過程或存儲函數(shù)的信息都被列出。PROCEDURE和FUNCTIOn分別表示查看存儲過程和函數(shù),LIKE語句表示匹配存儲過程或函數(shù)的名稱。
舉個例子:
SHOW PROCEDURE STATUS
運行結(jié)果為:
后面還有一些字段,截圖截不全沒辦法。查看存儲函數(shù)也一樣,可以自己試試看。
2、查看存儲過程和函數(shù)的定義
除了SHOW STATUS外,還可以使用SHOW CREATE來查看存儲過程的定義,基本格式為:
SHOW CREATE {PROCEDURE | FUNCTION} sp_name
比如:
SHOW CREATE FUNCTION NameByZip
我查看了NameByZip這個函數(shù)的定義,結(jié)果為:
這個Create Function字段就是創(chuàng)建的存儲函數(shù)的內(nèi)容
3、刪除存儲過程和函數(shù)
刪除存儲過程核函數(shù),可以使用DROP語句,基本語法如下:
DROP {PROCEDURE | FUNCTION} [IF EXISTS] sp_name
這個語句被用來移除一個存儲過程或函數(shù)。sp_name為待移除的存儲過程或函數(shù)的名稱。
IF EXISTS子句是一個MySQL的擴(kuò)展,如果程序或函數(shù)不存儲,它可以防止錯誤發(fā)生,產(chǎn)生一個用SHOW WARNINGS查看的警告。舉個例子:
DROP PROCEDURE CountStudent
DROP FUNCTION NameByZip;
這么簡單就可以了。注意這里沒有講修改存儲過程和存儲函數(shù),因為修改存儲過程或者函數(shù)只能修改存儲過程或者存儲函數(shù)的特性,不能直接對已有的存儲過程或函數(shù)進(jìn)行修改,如果必須要改,只能先DROP在重新編寫代碼,CREATE一個新的。
總結(jié)
以上是生活随笔為你收集整理的mysql 扩展存储过程_MySQL4:存储过程和函数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 注解 target_详解JDK
- 下一篇: babylonjs 设置面板位置_一篇关