存儲過程(Stored Procedure)是在大型數據庫系統中,一組爲了完成特定功能的SQL 語句集,存儲在數據庫中,經過第一次編譯後調用時不需要再次編譯,用戶通過指定存儲過程的名字並給出參數(如果該存儲過程帶有參數)來執行它。存儲過程是數據庫中的一個重要對象。
MySQL存儲函數(簡稱MySQL函數),是一種控制流程函數,屬於數據庫語言。
——百度百科
一、存儲過程
在普通模式下獲取數據,用戶需要通過輸入SQL指令與數據庫進行交互;存儲過程則是編寫好的SQL指令,存儲在數據庫中,用戶操作時只需調用存儲過程,不用重新輸入繁雜冗餘的SQL指令。
那麼,存儲過程都有哪些優點呢?
(1)存儲過程可以重複使用,減小開發人員的負擔;
(2)對於網絡上的服務器,可以減少網絡流量,因爲只需傳輸存儲過程的名稱即可;
(3)可以防止對錶的直接訪問,只需賦予用戶對存儲過程的訪問權限。
在MySQL中,創建存儲過程,使用CREATE PROCEDURE。
存儲過程創建後,用CALL語句可以調用存儲過程。在存儲過程內還可以調用其他存儲過程。
操作 | SQL命令 |
創建存儲過程 | CREATE PROCEDURE 存儲過程名(參數種類1 參數1 數據類型1,[…] BEGIN 具體的procedure(處理) END |
查看數據庫中的存儲過程 | SHOW PROCEDURE STATUS\G |
查看具體的存儲過程 | SHOW CREATE PROCEDURE 存儲過程名\G |
調用(執行)存儲過程 | CALL 存儲過程名(參數1,…); |
刪除存儲過程 | DROP PROCEDURE 存儲過程名 |
變量聲明 | DECLARE 變量名 數據類型; |
變量賦值 | SET 變量名= ; |
其中,參數種類包括IN,OUT和INOUT。IN表示輸入參數,OUT表示輸出參數,INOUT表示既可以輸入也可以輸出。
參數的數據類型可以是MYSQL數據庫中的任意類型。
案例如下:
(1)帶輸入和輸出參數的存儲過程:
/* 如果存在指定存儲過程名則刪除 */
mysql> drop procedure if exists sp1;
Query OK, 0 rows affected
/* 設置分隔符爲// */
mysql> delimiter //
mysql> create procedure sp1(in a int,in b int,out s int)
-> begin
-> set @ss=a+b;
/* 用@符號加變量名的方式定義一個變量,與declare類似 */
-> set s=@ss;
/* 語句體內可以執行多條sql,但必須以分號分隔 */
-> end//
Query OK, 0 rows affected
/* 將分隔符改回爲分號; */
mysql> delimiter ;
/* 調用該存儲過程,注意:輸入參數是一個值,而輸出參數則必須是一個帶@符號的變量 */
mysql> call sp1(3,5,@ret);
Query OK, 0 rows affected
mysql> select @ret;
+------+
| @ret |
+------+
| 8 |
+------+
1 row in set
(2)既做輸入又做輸出參數的存儲過程:
mysql> drop procedure if exists sp3;
Query OK, 0 rows affected
mysql> delimiter //
mysql> create procedure sp3(inout p int)
-> begin
-> if p=4 then
-> set @result=400;
-> else
-> set @result=500;
-> end if;
-> select @result;
-> end//
Query OK, 0 rows affected
mysql> delimiter ;
mysql> call sp3(@ret);
+---------+
| @result |
+---------+
| 500 |
+---------+
1 row in set
Query OK, 0 rows affected
mysql> set @ret=4;
Query OK, 0 rows affected
mysql> call sp3(@ret);
+---------+
| @result |
+---------+
| 400 |
+---------+
1 row in set
Query OK, 0 rows affected
二、存儲函數
創建存儲函數,需要使用CREATE FUNCTION語句,基本語法如下:
CREATE FUNCTION func_name([func_parameter])
RETURNS TYPE
[characteristics...]
CREATE FUNCTION爲用來創建存儲函數的關鍵字;func_name表示存儲函數的名稱
func_parameter爲存儲函數的參數列表,參數列表如下:
[IN|OUT|INOUT]PARAM_NAMETYPE
其中,IN表示輸入參數,OUT表示輸出參數,INOUT表示既可以輸入也可以輸出;
param_name表示參數名稱;type表示參數類型,該類型可以是MYSQL數據庫中的任意類型
RETURNS TYPE語句表示函數返回數據的類型;characteristics:指定存儲函數的特性,取值與創建存儲過程時相同。
示例:
mysql> delimiter //
mysql> create function test2()
-> returns varchar(50)
-> begin
-> return (select userName from user where id=2);
-> end //
Query OK, 0 rows affected
mysql> delimiter ;
mysql> select test2();
+---------+
| test2() |
+---------+
| root |
+---------+
1 row in set
三、總結
存儲過程和存儲函數都是存儲在服務器端的SQL語句的集合,要使用這些已經定義好的存儲過程和存儲函數就必須要通過調用的方式來實現。
存儲過程是通過CALL語句來調用的。而存儲函數的使用方法與MySQL內部函數的使用方法是一樣的。
執行存儲過程和存儲函數需要擁有EXECUTE權限;EXECUTE權限的信息存儲在information_schema數據庫下面的USER_PRIVILEGES表中。
存儲過程和函數創建以後,可以查看存儲過程和函數的狀態和定義。
通過SHOW STATUS語句來查看存儲過程和函數的狀態,也可以通過SHOW CREATE語句來查看存儲過程和函數的定義。
通過查詢information_schema數據庫下的Routines表來查看存儲過程和函數的信息。
存儲過程裏面是可以調用其他存儲過程的,使用CALL語句調用其他存儲過程就可以了;存儲過程參數列表裏的參數名儘量不要和數據庫中表的字段名一樣,否則有可能出錯;存儲過程的參數可以使用中文,在定義存儲過程的時候加上character set gbk就可以了。例:
CREATE PROCEDURE useInfo(IN u_name VARCHAR(50) CHARACTER SET gbk,OUT u_age INT);