MySQL之变量及游标使用的注意事项

在MySQL存储过程中,我们经常会用到变量的声明定义和游标的声明和使用。对初学者而言,可能会遇到一系列的小问题。此文将结合自己实践中遇到的一些问题进行梳理,总结如下。

1.MySQL变量

MySQL存储过程中,常用的变量有:局部变量、用户变量以及系统变量。

(1)局部变量

局部变量的作用域是BEGIN…END语句块内;使用DECLARE关键字来进行声明;使用SET关键字来定义。比如:

注意:DECLARE声明的变量名,一定不要和表的字段名相同。否则当该变量用于存储游标FETCH的数据时,会出现FETCH提取不出相应的数据至该同名变量中的问题。谨记。

建议:养成良好的命名习惯,变量名和字段名不要同名。例如表字段采用下划线命名规则——dev_id,而变量名采用驼峰命名规则——devId。

(2)用户变量

用户变量以一个@开头,它也可以用于BEGIN…END内使用,但是其作用域要比局部变量更大,只有在当前数据库连接断开的时候才会失效;

使用关键字set和select定义,但是不能忘记符号@。比如:

注意:此处声明的是用户变量(以@开头),在后续的操作中用到该变量时,一定不能省略了@符号,否则就成了前面介绍的局部变量了。

建议:如果一个存储过程不是很长(建议不超过200行),在使用一种类型的变量就可以完成工作的话,最好就使用一种类型的变量。比如,某个存储过程中只使用局部变量或者只使用用户变量。

(3)系统变量

系统变量以两个@开头,如@@var。实际工作中很少用到,此处不述,有兴趣的读者可以查询相关资料。

2. 游标遍历问题

MySQL的游标提供了很好的可以遍历指定查询结果集的这个功能,该功能一般会用在存储过程的循环体中,对结果集中的每条记录进行遍历和操作。

然而,FETCH语句提取结果集中的记录,有时会隐藏着陷阱。比如,有如下示例:

此时,结果集中的最后一条记录会被插入两次,即表tablename中存在两条相同的记录。

这是为什么呢?这是因为结果集最后一条记录提取之后,还会再提取一次才会发现游标已经遍历到了结果集的末尾了,虽然这次没有提取出有效数据,但是var1,var2中却保存着上一次提取的内容,而此时的循环体还将再执行一次。因此,造成了数据重复插入的问题。

那么,如何避免这种情况呢?建议:

在REPEAT之前FETCH一次记录后再进入循环体,并且在循环体的末尾再进行一次FETCH提取记录。比如:

这样,就可以解决结果集中最后一条记录被操作两次的问题。

3.其他

MySQL命令行登陆时需要注意的一点是:-p选项后面不能跟空格,比如-p passwd,是错误的。而-u选项后面跟不跟空格都可以。

发表评论

电子邮件地址不会被公开。 必填项已用*标注