1、基本介紹mysql
存儲過程和函數是事先通過編譯並存儲在數據庫中的一段SQL語句的集合,減小數據在數據庫和應用服務之間的傳輸,對於提升數據處理的效率是有好處的。sql
存儲過程和函數的區別在於 函數必須有返回值,而存儲過程沒有,存儲過程的參數可使用IN、OUT、INOUT類型,而函數的參數只能是IN類型的。若是有函數從其餘類型的數據庫遷移到MySQL,可能須要將函數改形成存儲過程。數據庫
存儲過程和函數容許包含DDL語句,也容許使用事務,還能夠調用其餘的存儲過程和函數,但不容許執行 Load Data Infile 語句;服務器
2、相關操做函數
建立存儲過程或函數須要 CREATE ROUTINE 權限,修改或刪除存儲過程或函數須要 ALTER ROUTINE 權限,執行存儲過程或函數須要 EXECUTE 權限。oop
建立、修改存儲過程或函數fetch
Create procedure sp_name([proc_parameter[,…])spa
[characteristic…] routine_body3d
Create function sp_name([func_parameter[,…])code
Returns type
[characteristic…] routine_body
Return xxx
調用語法:call sp_name([parameter[,…])
參數說明:
pro_parameter
[ IN | OUT | INOUT ] param_name type
func_parameter
param_name type
存儲過程和函數中不容許執行 LOAD DATA INFILE 語句。
Delimiter $$ 修改命令結束符
Characteristic特徵值:
Language sql 說明下面body是使用sql編寫,系統默認
Sql security{ definer | invoker } 能夠指定子程序該用建立子程序者的許可來執行仍是使用調用者的權限執行。默認是definer
Comment ‘string’ 存儲過程或函數的註釋信息
{ Contains sql | no sql | reads sql data | modifies sql data} 供子程序使用數據的內在信息,目前只提供給服務器,並無根據這些特徵值來約束過程實際使用數據的狀況,默認是contains sql;
-
- Contains sql 表示子程序不包含讀或寫數據的語句。
- No sql 表示子程序不包含sql語句。
- Reads sql data 表示子程序包含讀數據的語句,但不包含寫數據的語句。
- Modifies sql data 表示子程序包含寫數據的語句。
實例:
返回值用 @xxx
刪除存儲過程或函數:
一次只能刪除一個存儲過程或函數,需 ALTER ROUTINE 權限
Drop procedure name;
查看存儲過程或者函數:
查看存儲過程或函數的狀態:
Show { procedure | function } status [like ‘pattern’];
查看存儲過程或函數的定義:
Show create { procedure | function } name;
經過查看information_schema.Routines瞭解存儲過程和函數的信息
Select * from Routines where routine_name = 「name」;
3、變量的使用
變量不區分大小寫
變量的定義
Declare 定義一個局部變量,做用域在 BEGIN … END 塊中,能夠用在嵌套的塊中。必須寫在複合語句的開頭,而且在任何其餘語句的前面。可一次聲明多個相同類型的變量。如須要,可使用default賦默認值。
Declare var_name[,…] type [default value];
變量的賦值
變量能夠直接賦值,或者經過查詢賦值。直接賦值使用set,能夠賦常量或者賦表達式。
Set var_name = expr [,var_name = expr] …
Select col_name [,…] INTO var_name [,…] from xxx….; #查詢結果必須只有一行
Set @a = xxx; 至關於全局變量
定義條件和處理:
處理過程當中遇到問題時相應的處理步驟。
條件定義
Declare condition_name CONDITION FOR condition_value
條件處理(遊標中有實例)
Declare handler_type HANDLER FOR condition_value [,…] sp_statement
說明:
Handler_type 目前支持 continue 和 exit ,continue繼續執行下面的語句,exit表示終止。
Condition_value 值能夠經過declare定義的 condition_name,能夠是SQLSTATE 的值或者mysql-error-code的值或SQLWARING、NOT FOUND、SQLEXECEPTION,這3個值是3種定義好的錯誤類別。
- SQLWARING 是對全部以01開頭的SQLSTATE代碼速記
- NOT FOUND 是對全部以02開頭的SQLSTATE 代碼速記
- SQLEXCEPTION 是對全部沒有被SQLWARING 或 NOT FOUND 捕獲的SQLSTATE 代碼速記
4、遊標的使用
對結果集進行循環的處理,包括光標的聲明、open、fetch 和 close。
1條sql,對應N條結果集的資源,取出資源接口/句柄,就是遊標,沿着遊標,能夠一次取出1行。好處是,每一行的處理權利在咱們手中。
遊標通俗來說至關於你買東西別人一件件的給你,而不是一會兒全給你。
執行沒有數據錯誤:
修改存儲過程:
BEGIN DECLARE row_id int; DECLARE row_dt varchar(50); DECLARE row_catalog int; DECLARE row_total int; DECLARE i int default 1; DECLARE getArticle CURSOR FOR select id,dt,catalog from tblarticle where catalog = 75; select count(*) INTO row_total from tblarticle where catalog=75; OPEN getArticle; WHILE i<=row_total DO FETCH getArticle into row_id, row_dt, row_catalog; SELECT row_id, row_dt, row_catalog; set i = i+1; END WHILE; CLOSE getArticle; END
BEGIN DECLARE row_id int; DECLARE row_dt varchar(50); DECLARE row_catalog int; DECLARE row_total int; DECLARE i int DEFAULT 1; DECLARE getArticle CURSOR FOR select id,dt,catalog from tblarticle where catalog = 75; DECLARE EXIT HANDLER FOR NOT FOUND set i = 0; OPEN getArticle; REPEAT FETCH getArticle into row_id, row_dt, row_catalog; SELECT row_id, row_dt, row_catalog; UNTIL i = 0 END REPEAT; CLOSE getArticle; END
Declare continue/exit handler for not found close 遊標名;
Continue 和 exit 的區別:
遊標循環讀取的正確邏輯:
5、流程控制
If 、case、loop、leave、iterate、repeat、while語句
If語句
IF search_condition THEN statement_list
[ELSEIF search_condition THEN statement_list]…
[ELSE statement_list]
END IF ;
While語句
WHILE search_condition Do
Statement_list
END WHILE [end_label] ;
case語句
repeat語句(相似do…while)
While 和 repeat 的區別:
While 是知足條件才執行循環,repeat是知足條件退出循環;
While在首次循環執行以前就判斷條件,因此循環最少執行0次,而repeat是在首次執行循環以後才判斷條件,相似do…while,因此循壞最少執行1次;