扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
在数据库中,游标是一个十分重要的概念。游标提供了一种对从表中检索出的数据进行操作的灵活手段,就本质而言,游标实际上是一种能从包括多条数据记录的结果集中每次提取一条记录的机制。游标总是与一条SQL 选择语句相关联因为游标由结果集(可以是零条、一条或由相关的选择语句检索出的多条记录)和结果集中指向特定记录的游标位置组成。当决定对结果集进行处理时,必须声明一个指向该结果集的游标。如果曾经用 C 语言写过对文件进行处理的程序,那么游标就像您打开文件所得到的文件句柄一样,只要文件打开成功,该文件句柄就可代表该文件。对于游标而言,其道理是相同的。可见游标能够实现按与传统程序读取平面文件类似的方式处理来自基础表的结果集,从而把表中数据以平面文件的形式呈现给程序。
创新互联主营环江网站建设的网络公司,主营网站建设方案,成都app软件开发,环江h5重庆小程序开发搭建,环江网站营销推广欢迎环江等地区企业咨询
我们知道关系数据库管理系统实质是面向集合的,在MS SQL SERVER 中并没有一种描述表中单一记录的表达形式,除非使用where 子句来限制只有一条记录被选中。因此我们必须借助于游标来进行面向单条记录的数据处理。由此可见,游标允许应用程序对查询语句select 返回的行结果集中每一行进行相同或不同的操作,而不是一次对整个结果集进行同一种操作;它还提供对基于游标位置而对表中数据进行删除或更新的能力;而且,正是游标把作为面向集合的数据库管理系统和面向行的程序设计两者联系起来,使两个数据处理方式能够进行沟通。
在数据库开发过程中,当你检索的数据只是一条记录时,你所编写的事务语句代码往往使用SELECT INSERT 语句。但是我们常常会遇到这样情况,即从某一结果集中逐一地读取一条记录。那么如何解决这种问题呢?游标为我们提供了一种极为优秀的解决方案——那就是使用游标。
从字面可以这么理解什么是游标,游标就像是水面上漂浮的一个标记,这个标记可以来回游动,一会游到这里一会游到那里,这里的河水可以理解为是数据的集合,这个标记就是在这些数据间来回游动。
为什么 MySQL 会有游标这个概念,由于 SQL 语言是面向集合的语句,它每次查询出来都是一堆数据的集合,没有办法对其中一条记录进行单独的处理。如果要对每条记录进行单独处理就需要游标。
游标其实就像是编程语言中的 for/foreach 循环,把一个数组(数据的集合)中每条数据一条一条地循环出来,然后你在 for/foreach 循环中使用判断语句对你感兴趣的数据进行处理。
哪里可以使用游标呢,函数,存储过程,触发器中都可以使用。
说完概念,就来看下游标的固定写法。不管概念是否理解,记住下面的固定模式也可以完成搬砖任务。
1、声明游标
SELECT 语句就是正常的查询语句,例如:SELECT id,age FROM table;
2、打开游标
在打开游标之前,游标定义的 SQL 语句是不执行的。
3、取出记录
将当前的记录数据存入变量。
当 FETCH 没有找到记录时会抛出异常,异常的定义需要下面的 HANDLER FOR 语句。
声明游标语句中的 SELECT 如果有多个字段,INTO 后面需要多个变量进行接收。
4、设置结束条件
这个语句的作用是指定一个条件,告诉程序所有数据已经循环完毕,可以结束了。由于游标是使用 WHILE 循环进行每条数据的读取,就需要给 WHILE 一个结束条件。
处理种类:可以是, EXIT 立即结束。CONTINUE 继续下面的处理。
异常的类型:一般指定为 NOT FOUND ,意思是没有找到任何数据。
异常发生时的处理:当异常发生时需要做的事情,这里一般改变一个变量的值来记录异常已经发生了,如如 SET flat = 1 详细用法查看下面的例子。
5、关闭游标
实战代码:
完毕,看懂没,如果没看懂没关系,游标处理是一套固定的格式,按照上面例子中固定的格式套入到你的程序就可以了。
MySQL 存储过程中,使用游标查询,返回的是结果集时,如何查看调用存储过程输出结果呢?
解决方案:存储过程不返回数据,但它能创建和填充另一个表。所以在存储过程运行中创建临时表。该临时表将保存存储过程中生成的结果集,在遍历游标时,用insert保存每条数据到临时表中。后续调用时可以用select语句查询临时表中的存储过程运行结果。
以下有 三种方式 使用游标创建一个存储过程,统计某一部门下的员工信息
方法一:Loop循环
调用存储过程:
方法二:While 循环
调用存储过程:
方法三:REPEAT 循环
调用存储过程:
上述三种实现方法在测试过程中遇到下述问题。
调用存储过程查询临时表输出结果时,会发现多循环了一次,像这样:
解决方法:
在遍历游标查询结果时,先判断游标的结束标志(done) 是否是为1,如果不是1,则向临时表中插入数据。
本文实例讲述了Mysql存储过程中游标的用法。分享给大家供大家参考。具体如下:
1.
批量插入商户路由关联数据:
DELIMITER
$$
USE
`mmm_mac`$$
DROP
PROCEDURE
IF
EXISTS
`批量插入商户路由关联数据`$$
CREATE
DEFINER=`root`@`%`
PROCEDURE
`批量插入商户路由关联数据`()
BEGIN
DECLARE
v_partner_no
VARCHAR(32);
DECLARE
v_partner_id
INT(11);
DECLARE
v_sc_pid
INT(11);
DECLARE
v_mac_no
VARCHAR(32);
DECLARE
v_mac_addr
VARCHAR(32);
DECLARE
n_mac_no
BIGINT;
DECLARE
n_mac_addr
BIGINT;
DECLARE
n_mac_addr_str
VARCHAR(32);
DECLARE
done
INT;
#取得商户数据
DECLARE
cur_partnerlist
CURSOR
FOR
SELECT
comp_id,
partner_no,
sc_pid
FROM
mmm_partner.anl_partner;
SET
n_mac_no
=
100000000;
SET
n_mac_addr
=
1000000000;
OPEN
cur_partnerlist;
REPEAT
FETCH
cur_partnerlist
INTO
v_partner_id,v_partner_no,v_sc_pid;
SET
v_mac_no
=
CONCAT('MAC',v_sc_pid,n_mac_no);
SET
n_mac_addr_str
=
CONCAT(SUBSTR(n_mac_addr,1,2),':',SUBSTR(n_mac_addr,3,2),':',SUBSTR(n_mac_addr,5,2),':',SUBSTR(n_mac_addr,7,2),':',SUBSTR(n_mac_addr,9,2));
SET
v_mac_addr
=
CONCAT('CC:',n_mac_addr_str);
SET
n_mac_no
=
n_mac_no
+
1;
SET
n_mac_addr
=
n_mac_addr
+
1;
#向t_machine_sc_config表中插入商户关联路由的数据
#insert
into
t_machine_sc_config(mac_no,
partner_no,
partner_id,
sc_pid,
mac_addr,
comp_id,
is_lock)
values('MAC2016000000001','44060430603381',1,4403,'C8:87:18:AB:79:66',1,1);
INSERT
INTO
t_machine_sc_config(mac_no,
partner_no,
partner_id,
sc_pid,
mac_addr,
comp_id,
is_lock)
VALUES(v_mac_no,v_partner_no,v_partner_id,v_sc_pid,v_mac_addr,1,1);
UNTIL
END
REPEAT;
CLOSE
cur_partnerlist;
END$$
DELIMITER
;
2.
更新商户表:
DELIMITER
$$
USE
`mmm_partner`$$
DROP
PROCEDURE
IF
EXISTS
`更新商户表`$$
CREATE
DEFINER=`root`@`%`
PROCEDURE
`更新商户表`()
BEGIN
DECLARE
v_partner_no
VARCHAR(32);
DECLARE
vpartner_no
VARCHAR(32);
DECLARE
v_partner_id
VARCHAR(32);
DECLARE
n
BIGINT;
DECLARE
partnerid_list
CURSOR
FOR
SELECT
comp_id
FROM
100msh_partner.anl_partner
WHERE
TRIM(partner_no)
=
'';
SET
vpartner_no
=
'2015415parno';
SET
n
=
10000000;
OPEN
partnerid_list;
REPEAT
FETCH
partnerid_list
INTO
v_partner_id;
SET
v_partner_no
=
CONCAT(vpartner_no,n);
SET
n
=
n
+
1;
UPDATE
mmm_partner.anl_partner
SET
partner_no
=
v_partner_no
WHERE
comp_id
=
v_partner_id;
UNTIL
END
REPEAT;
CLOSE
partnerid_list;
END$$
DELIMITER
;
希望本文所述对大家的mysql数据库程序设计有所帮助。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流