您当前的位置:首页 > 互联网教程

MySQL 游标的定义与使用

发布时间:2025-05-12 11:11:36    发布人:远客网络

MySQL 游标的定义与使用

一、MySQL 游标的定义与使用

从字面可以这么理解什么是游标,游标就像是水面上漂浮的一个标记,这个标记可以来回游动,一会游到这里一会游到那里,这里的河水可以理解为是数据的集合,这个标记就是在这些数据间来回游动。

为什么 MySQL会有游标这个概念,由于 SQL语言是面向集合的语句,它每次查询出来都是一堆数据的集合,没有办法对其中一条记录进行单独的处理。如果要对每条记录进行单独处理就需要游标。

游标其实就像是编程语言中的 for/foreach循环,把一个数组(数据的集合)中每条数据一条一条地循环出来,然后你在 for/foreach循环中使用判断语句对你感兴趣的数据进行处理。

哪里可以使用游标呢,函数,存储过程,触发器中都可以使用。

说完概念,就来看下游标的固定写法。不管概念是否理解,记住下面的固定模式也可以完成搬砖任务。

SELECT语句就是正常的查询语句,例如:SELECT id,age FROM table;

在打开游标之前,游标定义的 SQL语句是不执行的。

当 FETCH没有找到记录时会抛出异常,异常的定义需要下面的 HANDLER FOR语句。

声明游标语句中的 SELECT如果有多个字段,INTO后面需要多个变量进行接收。

这个语句的作用是指定一个条件,告诉程序所有数据已经循环完毕,可以结束了。由于游标是使用 WHILE循环进行每条数据的读取,就需要给 WHILE一个结束条件。

处理种类:可以是, EXIT立即结束。CONTINUE继续下面的处理。

异常的类型:一般指定为 NOT FOUND,意思是没有找到任何数据。

异常发生时的处理:当异常发生时需要做的事情,这里一般改变一个变量的值来记录异常已经发生了,如如 SET flat= 1详细用法查看下面的例子。

完毕,看懂没,如果没看懂没关系,游标处理是一套固定的格式,按照上面例子中固定的格式套入到你的程序就可以了。

二、存储过程中用什么可以替代游标

Mysql存储过程优化——使用临时表代替游标。

Mysql游标在操作小数据量时比较方便,效率可观,但操作大数据量,速度比较慢,甚至直接产生系统错误。

一般说来,当操作的数据超过1万条时,就避免用游标吧。

为了测试游标性能,写了下面一个游标对IDC_Gather_Info表中数据进行遍历

下面是当表中数据分别为15万、5万、1万时游标的表现:

1.数据量15万,存储过程执行失败,提示错误:Incorrect key file for table'/tmp/#sql_3044_0.MYI';try to repair it

2.数据量5万,执行成功,耗时31.051s

3.数据量1万,执行成功,耗时1.371s

1.数据量15万,执行成功,耗时8.928s

2.数据量5万,执行成功,耗时2.994s

3.数据量1万,执行成功,耗时0.634s

可以看到Mysql的游标在处理大一点的数据量时还是比较乏力的,仅适合用于操作几百上千的小数据量。

三、mysql 存储过程

存储过程是数据库存储的一个重要的功能,但是MySQL在5.0以前并不支持存储过程,这使得MySQL在应用上大打折扣。好在MySQL 5.0终于开始已经支持存储过程,这样即可以大大提高数据库的处理速度,同时也可以提高数据库编程的灵活性。

MySQL存储过程创建的格式:CREATE PROCEDURE过程名([过程参数[,...]])

mysql>CREATEPROCEDUREproc1(OUTsint)

->SELECTCOUNT(*)INTOsFROMuser;

注:

(1)这里需要注意的是DELIMITER//和DELIMITER;两句,DELIMITER是分割符的意思,因为MySQL默认以";"为分隔符,如果我们没有声明分割符,那么编译器会把存储过程当成SQL语句进行处理,则存储过程的编译过程会报错,所以要事先用DELIMITER关键字申明当前段分隔符,这样MySQL才会将";"当做存储过程中的代码,不会执行这些代码,用完了之后要把分隔符还原。

(1)这里需要注意的是DELIMITER//和DELIMITER;两句,DELIMITER是分割符的意思,因为MySQL默认以";"为分隔符,如果我们没有声明分割符,那么编译器会把存储过程当成SQL语句进行处理,则存储过程的编译过程会报错,所以要事先用DELIMITER关键字申明当前段分隔符,这样MySQL才会将";"当做存储过程中的代码,不会执行这些代码,用完了之后要把分隔符还原。

(2)存储过程根据需要可能会有输入、输出、输入输出参数,这里有一个输出参数s,类型是int型,如果有多个参数用","分割开。

(3)过程体的开始与结束使用BEGIN与END进行标识。