在MySQL存储过程的语句中有三个标准的循环方式:WHILE循环,LOOP循环以及REPEAT循环。还有一种非标准的循环方式:GOTO,不过这种循环方式最好别用,很容易引起程序的混乱,在这里就不错具体介绍了。
这几个循环语句的格式如下:
WHILE……DO……END WHILE
REPEAT……UNTIL END REPEAT
LOOP……END LOOP
GOTO。
1 有输入参数
DELIMITER $$
USE `vitigu`$$
DROP PROCEDURE IF EXISTS `demo2`$$
CREATE DEFINER=`root`@`localhost` PROCEDURE `demo2`(IN sid INT)
BEGIN
DECLARE stuid INT;
SELECT username FROM student WHERE id=sid;
END$$
DELIMITER ;
2 无输入参数
DELIMITER $$
USE `vitigu`$$
DROP PROCEDURE IF EXISTS `CursorDemo1`$$
CREATE PROCEDURE `vitigu`.`CursorDemo1`()
BEGIN
DECLARE stu_name VARCHAR(20);
DECLARE stu_age VARCHAR(20);
DECLARE done INT DEFAULT 0;
DECLARE cur_name CURSOR FOR SELECT username,age FROM `vitigu`.`student`;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done =1;
OPEN cur_name;
FETCH cur_name INTO stu_name,stu_age;
WHILE(done<>1)
DO
SELECT stu_name,stu_age;
FETCH cur_name INTO stu_name,stu_age;
END WHILE;
CLOSE cur_name;
END$$
DELIMITER ;
一、创建存储过程和函数
1、创建存储过程的基本形式:
create procedure sp_name
([proc_parameter[,…]])
[characteristic…]routine_body
例子:
创建一个名为num_from_employee的存储过程
delimiter &&
create procedure num_from_employee(in emp_id int,out count_num int)
reads sql data
begin
select count(*) into count_num
from employee
where d_id=emp_id;
end
&&
2、创建存储函数
create function sp_name([func_parameter[,…]])
returns type
[characteristic…]routine_body
例子:
创建一个名为name_from_employee的存储过程
delimiter &&
create function name_from_employee(emp_id int)
returns varchar(20)
begin
return (select name
from employee
where num=emp_id);
end
&&
3、变量的使用(declare关键字,作用范围是begin…end程序段)
(1)定义变量
定义变量my_sql,数据类型为int型,默认值为10。代码:
declare my_sql int default 10;
(2)为变量赋值
为变量my_sql赋值为30,代码:
set my_sql=30;
从表中查询id为2的记录,将该记录的d_id值赋给变量my_sql。代码:
select d_id into my_sql
from employee where id=2;
4、定义条件和处理程序(declare关键字)
(1)定义条件
declare condition_name condition for condition_value
condition_value: sqlstate[value] sqlstate_value|mysql_error_code
例子:
定义“error 1146(42s02)”这个错误,名称为can_not_find。可以用两种不同的方法来定义,代码:
方法一:使用sqlstate_value
declare can_not_find condition for sqlstate '42s02';
方法二:使用mysql_error_code
declare can_not_find condition for 1146;
(2)定义处理程序
declare handler_type handler for condition_value[,…] sp_statement
handler_type:continue|exit|undo
condition_value:sqlstate[value]sqlstate_value|condition_name|sqlwarning|not found|sqlexception|mysql_error_code
例子:
捕获sqlstate_value
declare continue handler for sqlstate '42s02'set @info='can not find';
捕获mysql_error_code
declare continue handler for 1146 @info='can not find';
先定义条件,然后调用
declare can_not_find condition for 1146;
declare continue handler for can_not_find @info='can not find';
使用sqlwarning
declare exit handler for sqlwarning set @info='error';
使用not found
declare exit handler for not found set @info='error';
使用sqlexception
declare exit handler for sqlexception set @info='error';
5、光标的使用
查询语句可能查询出多条记录,在存储过程和存储函数中使用光标来逐条读取查询结果集中的记录。光标的使用包括声明光标、打开光标、使用光标和关闭光标。光标声明必须在处理程序之前,并且在变量和条件之后。
(1)声明光标
下面声明一个名为cur_employee的光标
declare cur_employee cursor for select name,age from employee;
(2)打开光标
打开一个名为cur_employee的光标
open cur_employee;
(3)使用光标
使用一个名为cur_employee的光标,将查询出来的数据存入emp_name和emp_age这两个变量中:
fetch cur_employee into emp_name,emp_age;
(4)关闭光标
关闭名为cur_employee的光标。
close cur_employee;
6、流程控制的使用
(1)if 语句
例子:
if age>20 then set @count1=@count1+1;
elseif age=20 then @count2=@conut2+1;
else @count3=@count3+1;
end if;
(2)case语句
例子:
case age
when 20 then set @count1=@count1+1;
else set @count2=@count2+1;
end case;
也可以是:
case
when age=20 then set @count1=@count1+1;
else set @count2=@count2+1;
end case;
(3)loop语句
例子:
add_num: loop
set @count=@count+1;
end loop add_num;
add_num是循环语句开始标签
(4)leave语句
例子:
add_num: loop
set @count=@count+1;
if @count=100 then
leave add_num;
end loop add_num;
(5)iterate语句(与leave用法相同,指跳出本次循环)
例子:
add_num: loop
set @count=@count+1;
if @count=100 then
leave add_num;
else if mod(@count,3)=0 then
iterate add_num;
select * from employee;
end loop add_num;
(6)repeat语句
例子:
repeat
set @count=@count+1;
until @count=100
end repeat;
(7)while语句
例子:
while @count<100 do
set @count=@count+1;
end while;
二、调用存储过程和函数
1、调用存储过程
基本语法:call sp_name(参数列表)
例子:
delimiter &&
create procedure num_from_employee(in emp_id int,out count_num int)
reads sql data
begin
select count(*) into count_num
from employee
where d_id=emp_id;
end
&&
call num_from_employee(1002,@n);
查询的时候:select @n;
2、调用存储函数
例子:
delimiter &&
create function name_from_employee(emp_id int)
returns varchar(20)
begin
return (select name
from employee
where num=emp_id);
end
&&
delimiter ;
select name_from_employee(3);
三、查看存储过程和函数
(1)show status语句查看存储过程和函数
语法:
show procedure|function status like 'pattern';
例子:
show procedure status like 'num_from_employee'\G
(2)show create语句查看存储过程和函数
例子:
show create procedure num_from_employee\G
(3)从information_schema.routines中(存储过程和函数的信息存储在information—_schema数据库下的routines表中)
语法
select * from information_schema.routines
where routine_name='sp_name';
例子
select * from information_schema.routines
where routine_name='num_from_employee'\G
四、修改存储过程和函数
例子:修改存储过程
alter procedure num_from_employee
modifies sql data
sql security invoker;
例子:修改存储函数
alter function name_from_employee
reads sql data
comment 'find name';
五、删除存储过程和函数
基本形式:
drop {procedure|}function sp_name;