閱讀說明:最近在整理Java及相關技術的基礎知識。本文整理於《mysql5.7 從入門到精通》,大神應該不需要!有空整理mysql核心的時候大神再來指導。
適用人群:
不常寫mysql存儲過程的人
僅想看懂存儲過程的人
mysql學習中的人
1、創建存儲過程:
delimiter // 將存儲過程的結束符改為 // 。可以不改,這是為了 區分存儲過程結束符和sql語句的結束符,增加可讀 create procdure Proc() begin select * from t_user; end // 存儲過程結束 delimiter ; 將存儲過程的結束符改為 ;
2、變量的使用
2.1
定義變量
使用關鍵字 declare 來定義變量
DECLARE myparam INT default 100;
2.2
為變量賦值
set var_name = xx, var_age = yy ; //支持很多參數,一直寫下去就好了。 //先聲明,再賦值: declare var1,var2,var3 INT; set var1 = 10,var2 = 20; set var3 = var1 + var2;
3、定義條件和處理程序
3.1
定義條件
可以使用sqlstate定義,或者直接定義錯誤碼。定義之后,出現改錯誤碼並不會終止程序,而是會被捕捉然后處理
類似Java中的try....catch....
//方法一 declare command_not_allowed condition for sqlstate '42000'; //方法二 declare command_not_allowed condition for 1148;
3.2
定義處理程序
declare handler_type HANDLER FOR condition_value[,...] sp_statement // 定義說明: handler_type 可選值: 1.CONTINUE:表示遇到錯誤不處理,繼續執行; 2.EXIT:表示遇到錯誤馬上退出; 3.UNDO:表示遇到錯誤后撤回之前的操作,MySQL中暫時不支持。 condition_value 可選值: 1.SQLSTATE[VALUE] sqlstate_value:包含5個字符的字符串錯誤值; 2.condition_name:表示DECLARE CONDITION定義的錯誤條件名稱; //參看3.1 3.SQLWARNING:匹配所有已01開頭的SQLSTATE錯誤代碼; 4.NOT FOUND:匹配所有已02開頭的SQLSTATE錯誤代碼; 5.SQLEXCEPTION:匹配所有沒有被SQLWARNING或NOT FOUND捕獲的SQLSTATE錯誤代碼; 6.MySQL_error_code:匹配所有數值類型錯誤代碼
例子1:
//方法一:捕獲sqlstate_value declare condition handler for sqlstate '42S02' set @info='NO_SUCH_TABLE'; //方法二:捕獲mysql_error_code declare continue handler for 1146 set @info='NO_SUCH_TABLE'; //方法三:先定義條件,然后調用 declare no_such_table condition for 1146; declare continue handler for no_such_table set @info=' NO_SUCH_TABLE'; //方法四:使用SQLWARNING declare exit handler for SQLWARNING set @info='ERROR'; //方法五:使用NOT FOUND declare exit handler for not found set @info='NO_SUCH_TABLE'; //方法六:使用SQLEXCEPTION declare EXIT handler for SQLEXCEPTION set @info='ERROR';
例子2(完整執行sql):@x是1個用戶變量,根據查看@x的執行結果,可以知道程序執行到了哪一步,如果@x=1則只執行到第一條
insert語句,若@x=3則執行到了最后。
> create table test.t (s1 int,primary key (s1)); > delimiter // 將結束符定義為// // 創建存儲過程 > create procedure handlerdemo() > begin > declare continue handler for sqlstate '23000' set @x2 = 1; //23000 主鍵重復錯誤出現時,continue繼續執行。 > set @x = 1; > insert into test.t values (1); > set @x = 2; > insert into test.t values (1); > set @x = 3; > end; > delimiter ; // 調用存儲過程 > call handlerdemo(); // 查看存儲過程結果 > select @x;
用戶變量:使用 set @var_name 定義,用戶變量與連接有關,一個客戶端定義的變量不能被其他客戶端看到,用戶退出則自動釋放
4、光標的使用
光標:查詢語句返回多條記錄時,需要在存儲過程中使用光標來逐條讀取查詢結果集中的記錄。
4.1
聲明光標
declare cursor_name cursor for select_statement // 定義說明 cursor_name:光標名稱 select_statement:查詢select語句的內容 例子: declare cursor_fruit cursor for select f_name,f_price from fruits;
4.2
打開光標
open cursor_name(光標名稱)
fetch cursor_name into var_name [,var_name] ...(參數名) // 定義說明 var_name參數表示將光標中的select語句查詢出來的信息存入該參數中, var_name必須在聲明光標之前定義。
4.3
使用光標
fetch cursor_name into var_name [,var_name] ...(參數名) // 定義說明 var_name參數表示將光標中的select語句查詢出來的信息存入該參數中, var_name必須在聲明光標之前定義。
例子:
fetch cursor_friut into fruit_name,fruit_price;
4.4
關閉光標
close cursor_name(光標名稱)
5、流程控制
mysql中的流程控制語句:IF, CASE, LOOP, LEAVE, ITERATE, REPEAT, WHILE 語句
5.1
IF語句
語法格式
if expr_condition then statement_list [elseif expr_conditon then statement_list]... [else statement_list] end if // 定義說明 if 條件一 then 執行語句 [elseif 條件二 then 執行語句]... [else 執行語句] end if //終結符
例子
if val is null then select 'val is NULL'; else select 'val is not NULL'; end if;
5.2
CASE 語句
// 格式一 case case_expr when when_value then statement_list [when when_value then statement_list] ... [else statement_list] end case // 格式二 ,此條件下,when語句將逐一執行,直到某個expr_condition為真 case when when_value then statement_list [when when_value then statement_list] ... [else statement_list] end case 例子 // 格式一 case val when 1 then select 'val is 1'; when 2 then select 'val is 2'; else select 'val is not 1 or 2'; end case; // 格式二 case when val is NULL then select 'val is NULL'; when val < 0 then select 'val is less than 0'; when val > 0 then select 'val is greater then 0'; end case;
5.3
LOOP 語句
loop語句:創建一個循環操作,使用leave退出循環 [loop_label:] LOOP statement-list end LOOP [loop_label] // 參數說明 loop_label:loop語句的標注名稱,非必填。
例子
declare id int default 0; add_loop:LOOP set id = id + 1; if id >= 10 then leave add_loop; //id大於等於10時退出循環 end if; end loop add_loop;
5.4
LEAVE 語句
leave語句用來退出任何被標注的流程控制構造,參看上述例子。 leave label 例子 add_num:LOOP set @count = @count+1; if @count = 50 then leave add_num; end LOOP add_num;
5.5
ITERATE 語句
將執行順序轉到語句段開頭處。只可以出現在loop、repeat、while語句內。意為“再次循環”
iterate label // 參數說明 label:循環標志。iterate語句必須跟在循環標志前面
例子
create procedure doiterate() begin declare p1 int default 0; my_loop:LOOP set p1 = p1 + 1; if p1 < 10 then iterate my_loop; elseif p1 > 20 then leave my_loop; end if; select 'p1 is between 10 and 20'; end LOOP my_loop; end
5.6
REPEAT 語句
創建帶條件判斷的循環過程,每次語句執行完畢,再判斷條件。類似直到型循環! [repeat_label:]REPEAT statement_list until expr_condition end repeat [repeat_label] // 參數說明 repeat_label 為REPEAT語句的標注名稱。改參數可以省略;
例子
declare id int default 0; repeat set id = id +1; until id >= 10 end repeat;
5.7
WHILE 語句
當型循環
[while_label:] WHILE expr_condition DO statement_list END WHILE [while_label] // 參數說明 while_label:標注名稱,可省略。
例子
declare i int default 0; while i < 10 DO set i = i + 1; end while;
6、調用存儲過程/函數
6.1
調用存儲過程
調用:
CALL sp_name([parameter[,....]]) // 參數說明 sp_name:存儲過程名稱 parameter:存儲過程參數
例子
// 創建存儲過程: > delimiter // > crate procedure CountProc1 (IN sid int,OUT num int) > begin > select count(*) into num from fruits where s_id = sid; > end // > delemiter ; // 調用存儲過程 > CALL CountProc1 (101,@num) // 查看返回結果 > select @num;
6.2
調用存儲函數
// 定義存儲函數 > delimiter // > create function CountProc2 (sid int) > returns int > begin > return (select count(*) from fruits where s_id = sid); > end // > delimiter ; //調用存儲函數: > select CountProc2(101);
7、查看存儲過程/函數
7.1
SHOW STATUS
SHOW {procedure | function} STATUS [LIKE 'pattern']
例子
//獲取字母‘C’開頭的存儲過程信息 show procedure status like 'C%' \G
7.2
SHOW CREATE
SHOW CREATE {procedure | function} sp_name //參數說明 sp_name:存儲過程或函數的名稱
例子
show create function test.CountProc \G
7.3
從information_schema.Routines表中查看
mysql的存儲過程和函數信息存儲在information_schema數據庫的Routines表中。
select * from information_schema.Routines where ROUTINE_NAME = 'CountProC' and ROUTINE_TYPE = 'FUNCTION' \G
8、修改/刪除存儲過程/函數
8.1
修改存儲過程/函數
ALTER {PROCEDURE | FUNCTION} sp_name [characteristic ...] // 參數說明 sp_name:表示存儲過程或函數名稱 characteristic:指定存儲函數的特性 可選值: CONTAINS SQL:表示子程序包含sql語句,但不包含讀或寫數據的語句。 NO SQL:表示子程序中不包含sql語句。 READS SQL DATA 表示子程序中包含讀數據的語句。 MODIFIES SQL DATA 表示子程序中包含寫數據的語句。 SQL SECURITY {DEFINER | INVOKER} 指明誰有權限來執行。 DEFINER表示只有定義這自己才能夠執行。 INVOKER表示調用者可以執行。 COMMENT'string'表示注釋信息。
> alter procedure CountProc > modifies sql data > sql security invoker;
例子2
> alter function CountProc > reads sql data > comment 'find name';
8.2
刪除存儲過程/函數
DROP {PROCEDURE | FUNCTION} [IF EXISTS] sp_name
drop procedure CountProc;
drop function CountProc;