存储过程就是一组为完成某项特定功能的sql语句集。按我的理解,就是一个封装好的方法,可以被访问。
这里就应该讲到存储过程的高性能。存储过程执行一次后,其执行规划就驻留在高速缓冲存储器中,在以后的操作,会直接从高速缓存中调用已经编译好的二进制代码,提高效率。
以下通过一个小例子说明,将逐行解释。
Delimiter @@
create proceduce test_proceduce(out rows int)
begin
declare cid int;
declare isFound tinyint default 1;
declare cur_cid cursor for select cust_id from customers;
declare continue handler for not found
set isFound = 0;
set rows = 0;
open cur_cid;
fetch cur_cid into cid;
while isFound = 1 do
set rows = rows + 1;
fetch cur_cid into cid;
end while;
close cur_cid;
end @@
Delimiter ;
1、第一行,Delimiter @@
delimiter:修改mysq的语句结束标识。首先我们都知道mysql默认语句结束标识是 ;(分号),但一个存储过程体,可能包含多条sql语句,以分号结尾,可能mysql 不会去执行后面的语句,会有很多不可预知的问题。所以,我们首先将mysql默认结束标识改为 @@ ,到存储过程结束后,再改回 ; (分号)
2、第二行,create proceduce …
mysql使用 create proceduce语句创建存储过程 语法为:
create proceduce sp_name(proc_parameter[,...])
routime_body
proc_parameter是用于指定存储过程的参数列表 语法格式:
[in|out|inout] param_name type
a)in out inout 是mysql存储过程的三种类型参数,即 输入参数,输出参数 和 输入\输出参数
b)param_name 是参数名称
c)type 是参数类型 可以是任何有效的mysql数据类型
routime_body 存储过程的主体部分 基本格式为:
begin
...
end
存储过程体只有一条sql的时候,begin end 可以省略,begin end 复合语句可以嵌套使用。
正如上面代码所示,我们创建了一个名为test_proceduce的存储过程,输出名字为rows,类型为int的参数。
3、第四行,第五行,declare cid int;declare isFound …
declare:声明局部变量,同时可以为局部变量赋初始值 其语法格式:
declare var_name[,..] type [default value]
4、第六行、第十行、第十一行、第十六行 declare cur_cid cursor for…
这几行涉及到一个游标的概念
cursor(游标): 游标是一个被select语句检索出来的结果集。可以理解成一个数据集合
a)声明游标
declare cursor_name cursor for select_statement
cursor_name 游标名称
select_statement 指定一个sql语句
正如第六行,我们声明了一个叫做cur_cid的游标,他的内容是
select cust_id from customers 返回的结果
b)打开游标
游标只有打开了,才能用
open cursor_name
第十行,我们打开了游标
c)读取游标内容
fetch cursor_name into
十一行,我们读取了游标的第一个内容,并赋给了cid
d)关闭游标
游标使用结束,必须关闭游标
close cursor_name
十六行,我们关闭了游标
5、先看第九行 set rows = 0;
set: 使用set语句为局部变量赋值,语法格式:
set var_name = expr[, var_name=expr] ...
第九行,我们设置rows 等于0
6、第七行、第八行 declare continue handler
declare handler 声明一个异常处理,语法格式如下:
DECLARE
{EXIT | CONTINUE}
HANDLER FOR
{error-number | SQLSTATE error-string | condition}
SQL statement
a)continue 表示捕获了异常,继续执行下面的代码
b)exit 表示捕获了异常,退出当前所在的复合语句 当然set isFound=0还是会执行
c){error-number | SQLSTATE error-string | condition} 包括
1、MYSQL错误代码
2、ANSI-standard SQLSTATE code
3、命名条件。可使用系统内置的SQLEXCEPTION,SQLWARNING和NOT FOUND
正如第七行,第八行,我们声明了一个异常处理,当程序块出现not found 异常的时候,执行 set isFound = 0; 这个概念类似于我们Java的try … catch一样。我们try的范围是整个代码块,catch了 not found exception finally 执行set isFound = 0;
7、第十二行、第十五行 while ..do ..
mysql 支持条件判断语句和循环语句这两类用于控制语句流程的过程式sql语句,这里明显是一个循环语句.
mysql三种标准循环语句格式:
WHILE……DO……END WHILE
REPEAT……UNTIL END REPEAT
LOOP……END LOOP
这里的循环其实跟高级程序设计语言的思想相同,所以就解释了。
8、第十三行、十四行 set… ; fetch .. into..
mysql中,使用set 给变量赋值
mysql中,使用fetch xxx into xx 取游标的值
9、第十六行 close cur_cid
关闭游标 (游标open后,都需要关闭)
declare handler 部分摘自
https://www.cnblogs.com/datoubaba/archive/2012/06/20/2556428.html