3.1 概述
- 存储过程和函数是事先编译并存储在数据库中的一段SQL语句的集合
- 存储过程没有返回值
- 存储函数有返回值
- 优点
- 减少数据在数据库和应用服务器之间的传输,提高处理效率
3.2 创建存储过程
CREATE PROCEDURE procedure_name(参数)begin-- SQL语句end;//需要指定分隔符
delimiter $create procedure pro_test01()beginselect * from a;//不会;立即执行了end$delimiter ;//复原
3.3 调用存储过程
call pro_test01();
3.4 查看存储过程
查找proc表
select name from mysql.proc where db = 'db_name';
查询存储过程的状态信息
show procedure status\G;
查询某个存储过程的定义
show create procedure db_name.pro_test01\G;
3.5 删除存储过程
drop procedure pro_test01;
3.6 语法结构
存储过程是可以编程的,意味着可以使用变量、表达式、控制结构来完成比较复杂的功能。
3.6.1 变量
DECLARE
- 定义一个局部变量
作用范围只能在BEGIN…END块中 ```sql delimiter $ create procedure test02() begin
declare num int default 10; select concat(‘num:’,num); end$
delimiter ;
- SET- 给变量赋值- 可以赋值常量或表达式```sqldelimiter $create procedure test03()begindeclare name varchar(20);set name = 'mysql';select name;end$delimiter ;
SELECT INTO ```sql delimiter $ create procedure test03() begin
declare num int; select count(*) into num from city; select concat(“city表中的记录数:”,num); end$
delimiter ;
call test03();
<a name="J9rr9"></a>###<a name="Xvk2J"></a>### 3.6.2 IF条件判断```sqldelimiter $crete procedure test04()begindeclare height int default 175;declare description varchar(50) default '';if hegiht >= 180 thanset description = 'tall';elseif height>=170 and height <180 thanset description = 'ok';elseset description = 'short';end if;select height,description;end$
3.6.3 传递参数
- IN
- 输入参数(默认) ```sql delimiter $
crete procedure test05(IN height int) begin
declare description varchar(50) default ‘’;
if hegiht >= 180 than set description = ‘tall’; elseif height>=170 and height <180 than set description = ‘ok’; else set description = ‘short’; end if;
select height,description; end$
call test05(175);
- OUT- 输出参数(返回值)- @varname:用户会话变量,类似于全局变量- @@global:系统变量```sqldelimiter $crete procedure test05(IN height int,OUT description varchar(10))beginif hegiht >= 180 thanset description = 'tall';elseif height>=170 and height <180 thanset description = 'ok';elseset description = 'short';end if;end$call test05(175,@description);select @description;set @name='aaa';
- INOUT
- 既是输出又是输入
3.6.4 case结构
delimiter $create procedure pro_test7(month int)begindeclare result varchar(10);casewhen month >= 1 and month<=3 thenset result = "第一季度";when month >= 4 and month<=6 thenset result = "第二季度";when month >= 7 and month<=9 thenset result = "第三季度";elseset result = "第四季度";end case;select result;end$
3.6.5 while
- 满足条件循环
- while [statement] do…end while; ```sql delimiter $
create procedure pro_test8(n int) begin
declare totle int default 0;
declare num int default 1;
while num<=n doset total = total+num;set num = num+1;
end while;
select total;
end$
<a name="BdUAR"></a>###<a name="bmyOz"></a>### 3.6.6 repeat- 满足条件退出循环- repeat [statement] util... end repeat;```sqldelimiter $create procedure pro_test9(n int)begindeclare totle int default 0;repeatset total = total+n;set n = n-1;until n = 0 -- !!!!!!!!!!!!!没有分号!!!!!!!!!!!!!!!end repeat;select total;end$
3.6.7 loop
- 退出循环需要其他语句定义(LEAVE)
- c:loop
- [statement]
- if [statement] then
- leave c;
- end if;
- end loop c; ```sql delimiter $
- c:loop
create procedure pro_test10(n int) begin
declare totle int default 0;
c:loop
set total = total+n;set n = n-1;if n<0 thenleave c;endif;
end loop c;
select total;
end$
<a name="jwuE6"></a>###<a name="kA9YV"></a>### 3.6.8 游标/光标- 用来**存储查询结果集**的数据类型,在存储过程和函数中可以使用光标**对结果集进行循环处理**。- 声明光标(DECLARE)- OPEN光标- FETCH光标- 每抓取一条数据,fetch指针向下移动一个- CLOSE光标```sqlcreate procedure pro_test01()begindeclare eid int(11);//和表中的类型要一致declare e_name varchar(50);declare emp_result cursor for select * from emp;open emp_result;fetch emp_result into e_id,e_name;//每fetch一次读取一行select concat('id=',e_id,'name=',e_name);close emp_result;end$call pro_test01();//读取一行
create procedure pro_test01()begindeclare eid int(11); -- 和表中的类型要一致declare e_name varchar(50);declare has_data int default 1; -- has_data==0,退出循环declare emp_result cursor for select * from emp;declare exit HANDLER for not found set has_data=0; --退出条件写在定义游标之后open emp_result;repeatfetch emp_result into e_id,e_name;//每fetch一次读取一行select concat('id=',e_id,'name=',e_name);until has_data = 0end repeat;close emp_result;end$call pro_test01(); -- 循环读取
3.7 存储函数
- 类似,有返回值 ```sql create function func1(countryID int) returns int begin declare cnum int; select count(*) into cnum from city where country_id = countryID; return cnum; end$
select func1(1);
drop function func1; ```
