mysql存儲過程學習


閱讀說明:最近在整理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'表示注釋信息。

 

    例子1
> 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;
 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM