阅读说明:最近在整理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;