写mysql的sp真的很痛苦,一来语法要求及其严格,而且和普通编程语言区别较大,二来没有好的工具辅助.所以感觉痛苦.
语法需要注意的是赋值语句和循环语句.按照管理写i=i+1或者i+=1,或者i++都不好使.郁闷了半天才醒悟,原来赋值语句药加select或者是set.写作:set i = i + 1;
循环语句也很变态,各个版本支持的情况都不一样.以5.0.20为例,就不支持如下:
STU_loop:loop #遍历开始
fetchcursor into id;
if done=1 then leave loop;end if #完成则跳出循环;
#根据学生id将所有学生的相关信息拷贝过来
call copy_info_job(id);
end loop STU_loop;
这几句不能通过编译.相应的应该写为:
repeat
fetch student_cursor into student_id;
#其他语句
until student_done END REPEAT;
另外,游标的使用也值得注意.MYSQL中对于游标的支持不是很好,功能也不太强大,根据书上说是,游标只能向前游动,而不能后退.而且游到末尾了也不能自己停止而是会报错.我们只能根据错误代码写一个
出错处理程序才能够防止死循环.下面具体解释一个存储过程的执行过程.
DELIMITER $$
DROP PROCEDURE IF EXISTS `dbas`.`student` $$
CREATE PROCEDURE `copy_info_student`(in student_grade smallint)
BEGIN
#以上四句属于必写语句,没有什么好说的.
declare done int default 0; #the flag of complete loop;
declare id int default 0;
#以上两句是什么变量的语句.
declare cursor CURSOR For select id from student where grade = grade;
#上面一句是声明游标的语句,游标的结果集友select语句确定.
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
#上面一句是游标的出错处理程序,02000是游标越界的错误代号,出错置done为1;
open cursor;
#这句打开游标;
repeat
#循环开始
#select * from info_stu;
#带#号的语句是注释掉的,调试时候曾用过,现已无用.
fetch cursor into id;
#游标向前移动一个位置,并取值存入id中;
#select done;
#已经注释掉了
call copy_info_job(id);
call copy_fellback_log(id);
call copy_loan_bargain(id);
#以上三句是调用其他存储过程,在此忽略
until done END REPEAT;
#判断条件,done为真则循环结束,否则继续.
close cursor;
#关闭游标;
insert ......
update.....
select.....
#其他语句;
END $$
DELIMITER ;
#以上2句属于必写语句,没有什么好说的.