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;
 
 
凡你能说的,你说清楚。凡你不能说的,留给沉默!
原文地址:https://www.cnblogs.com/dhcao/p/9068944.html