使用Mysql实现一个存储过程,有以下几个结论:
1. 变量
Mysql中的变量,分系统变量和用户自定义变量:
系统变量:全局变量、会话变量;
用户自定义变量:用户变量和局部变量;
a) 系统变量
系统变量有系统进行定义,服务于服务器;比如日志配置;
全局变量使用global关键字,会话变量使用session关键字,默认会话变量;
show variables like '%log%';
set global log_output = 'TABLE';
# 修改日志记录方式为Table,保存到Mysql.general_log中,默认保存到data目录下的log文件中;
set global general_log ='ON';
set @@global.general_log = 'ON';
# 打开记录日志功能;每次重启服务都会自动关闭,除非修改配置文件;使用两种方式进行打开;
show global variables like '%log%';
select @@global.back_log;
select @@global.general_log;
# 显示系统变量的内容;
b) 用户自定义变量
用户自定义变量,有用户自行定义;用户变量作用于当前会话;局部变量用在begin和end之间,因此局部变量不能直接使用,一定要定义在函数或存储过程中;
区别:
1. 用户变量以@开始,局部变量为字符串,为了便于和字段进行区分,可以以"_"开始。
2. 用户变量不用定义,直接进行赋值即可;局部变量必须先定义再使用。
赋值方式:适用于2种变量,用变量名进行区分。
SET 变量名=值;
SELECT 变量名:=值;
SELECT 字段 INTO 变量名
2. 执行字符串
有时表名或字段是可变的,无法直接通过SQL语句实现,通过执行字符串方式实现;
DECLARE strSql text ;
set strSql = CONCAT('SELECT @count_num := COUNT(1) from ',tableName);
set strSql = CONCAT('SELECT COUNT(1) into @count_num from ',tableName);
# 上面两个语句作用相同,但是在存储过程中不同;第一句会产生一个输出,第二句不会。
SET @strSql = strSql;
PREPARE stmt FROM @strSql;
# 必须使用用户变量
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
set count_num = @count_num;
上述方式由于采用拼凑方式,有sql漏洞,最好采用下面语句:
DECLARE strSql text ;
set strSql = 'SELECT @count_num := COUNT(1) from ?';
set strSql = 'SELECT COUNT(1) into @count_num from ?';
# 上面两个语句作用相同,但是在存储过程中不同;第一句会产生一个输出,第二句不会。
SET @strSql = strSql;
PREPARE stmt FROM @strSql;
# 必须使用用户变量
set @table = tableName;
EXECUTE stmt using @table;
DEALLOCATE PREPARE stmt;
set count_num = @count_num;
3. 日志
在系统变量小节的示例代码,打开了日志功能,能记录执行的操作。对于存储过程内容的SQL语句,暂时没有找到记录的方法;dbForge Studio for MySQL能调试里面存储过程中的SQL语句,游标内部的语句设置了断点无效。
4. 游标
DECLARE _cur CURSOR for SELECT a,xh,ref_sql from _t1;
# 创建游标,并设置游标所指的数据
# 游标执行完,即遍历结束。设置done的值为1
DECLARE CONTINUE HANDLER for not FOUND set _done=1;
# 开启游标
open _cur;
fetch _cur into _a,_xh,_ref_sql;
while _done != 1 do
# -- 执行循环
fetch _cur into _a,_xh,_ref_sql;
end while;
-- 关闭游标
CLOSE _cur;