- 浏览: 235776 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
wuyang528378:
这样的方法的却能解决动态传参的问题,但是在并发访问时会有问题, ...
Mysql 游标使用动态变量 -
cctvmfc:
我用的tomcat7.0.55,步骤6没做,运行也是OK的
Solr4.10.3安装配置 -
popzh2004:
<lib dir="../../../cont ...
Solr4.10.3安装配置 -
HuNanPengdake:
另外告知看到本篇文章想踩的同学: 希望您踩的同时,留下您 ...
Solr4.10.3安装配置 -
lingyu50:
生成在JSP上没问题,但打印的时候,二维码这块打印不出来,何故 ...
Jquery生成二维码,支持中文
从语法上来讲DECLARE cur CURSOR for语句必须写在SET @sqlstr前面,这就意味着不能通过先执行一条动态语句根据结果拼凑游标的内容,而且游标在定义的时候也没有参数的概念,而是将定义的结构完全当作一个字符串直接处理,不会做任何的处理,也就是静态游标吧。关于dynamic cursor的内容官方有解释http://dev.mysql.com/doc/refman/5.6/en/connector-odbc-usagenotes-functionality.html#connector-odbc-usagenotes-functionality-dynamic-cursor我从5.1找到5.6只有这一个地方讲dynamic cursor而且内容一模一样。
“Support for the dynamic cursor is provided in Connector/ODBC 3.51, but dynamic cursors are not enabled by default. You can enable this function within Windows by selecting the Enable Dynamic Cursor check box within the ODBC Data Source Administrator.On other platforms, you can enable the dynamic cursor by adding 32 to the OPTION value when creating the DSN. ”话说这个意思是使用ODBC的话就可以经过设置之后使用dynamic cursor,关键是我有JDBC,安装程序的时候再自带一个ODBC驱动的话,貌似不太现实,于是考虑其它方式。我总结一下解决这个问题有三种途径。
一、避免使用动态游标的可能性。首先使用所谓动态就是一段代码可复用与多种情况,于是每种情况都写一种代码就可避免,但是作为开发人员,基本没人会这样做。
二、拆分存储过程。假设存在表结构如下:
现在的问题就是将不确定值传给游标,简单的游标定义如下DECLARE cur CURSOR for SELECT * FROM TABLE。这里看到好多人说法是如果在for语句后面使用内置方法方法的话,方法参数可以是你传入的值,也就是说后面的SQL语句是支持方法调用的。没测试,那天测试了再补充吧。就拿后面的 select 语句来说这个语句里面都是确定的值,但是有一个我们可以控制的参数就是表名。表这里可以看作是一个临时的数据集合,如果我们可以控制里面的值,在游标OPEN之后读这个“动态的集合”,于是实现这个有临时表和视图两种途径。在这里我选择视图。现在创建三个PROCEDURE:
第一个功能很简单,根据条件获得一个ID集合,并把集合存在tree_test_view这个视图中,这里直接在SQL编辑器写的代码,直接运行需要添加存储过程存在判断和DELIMITER转义换行符。现在我们已经获得需要要删除的树的ID集合,因为已只有两级的数,所有只需要知道根的id就可以直接删除整棵树,如果是多级的话就需要进行递归删除,当然前提是需要知道根ID,并且只知道根ID就足够了。
这个就是执行的删除操作,基本的游标循环操作,话说这写法好像很有shell和python的韵味。proc1和proc2两个分别执行就可已,当然为了对外的友好,可以再写一个进行统一调用:
三、第三种是我首先想到的,后来发现原来一般情况下会首先想到第二种,于是我觉得我确实懒的不行了。第三种方法实际就是第二种方法的偷懒方式,把所有的都放在一个存储过程中实现,实际SQL如下:
“Support for the dynamic cursor is provided in Connector/ODBC 3.51, but dynamic cursors are not enabled by default. You can enable this function within Windows by selecting the Enable Dynamic Cursor check box within the ODBC Data Source Administrator.On other platforms, you can enable the dynamic cursor by adding 32 to the OPTION value when creating the DSN. ”话说这个意思是使用ODBC的话就可以经过设置之后使用dynamic cursor,关键是我有JDBC,安装程序的时候再自带一个ODBC驱动的话,貌似不太现实,于是考虑其它方式。我总结一下解决这个问题有三种途径。
一、避免使用动态游标的可能性。首先使用所谓动态就是一段代码可复用与多种情况,于是每种情况都写一种代码就可避免,但是作为开发人员,基本没人会这样做。
二、拆分存储过程。假设存在表结构如下:
mysql> desc tree_test; +———–+————-+——+—–+———+—————-+ | Field | Type | Null | Key | Default | Extra | +———–+————-+——+—–+———+—————-+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(11) | NO | | | | | parent_id | int(11) | NO | | NULL | | +———–+————-+——+—–+———+—————-+ 3 rows in set (0.00 sec)
现在的问题就是将不确定值传给游标,简单的游标定义如下DECLARE cur CURSOR for SELECT * FROM TABLE。这里看到好多人说法是如果在for语句后面使用内置方法方法的话,方法参数可以是你传入的值,也就是说后面的SQL语句是支持方法调用的。没测试,那天测试了再补充吧。就拿后面的 select 语句来说这个语句里面都是确定的值,但是有一个我们可以控制的参数就是表名。表这里可以看作是一个临时的数据集合,如果我们可以控制里面的值,在游标OPEN之后读这个“动态的集合”,于是实现这个有临时表和视图两种途径。在这里我选择视图。现在创建三个PROCEDURE:
CREATE DEFINER=`root`@`localhost` PROCEDURE `proc1`(IN top int) BEGIN DROP VIEW IF EXISTS tree_test_view; SET @sqlstr = "CREATE VIEW tree_test_view as "; SET @sqlstr = CONCAT(@sqlstr , "SELECT id FROM tree_test WHERE parent_id = 0 LIMIT ", top); PREPARE stmt FROM @sqlstr; EXECUTE stmt; DEALLOCATE PREPARE stmt; END
第一个功能很简单,根据条件获得一个ID集合,并把集合存在tree_test_view这个视图中,这里直接在SQL编辑器写的代码,直接运行需要添加存储过程存在判断和DELIMITER转义换行符。现在我们已经获得需要要删除的树的ID集合,因为已只有两级的数,所有只需要知道根的id就可以直接删除整棵树,如果是多级的话就需要进行递归删除,当然前提是需要知道根ID,并且只知道根ID就足够了。
CREATE DEFINER=`root`@`localhost` PROCEDURE `proc2`() BEGIN DECLARE done INT DEFAULT 0; DECLARE temp_id INT; DECLARE cur CURSOR for( SELECT id from tree_test_view); DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; OPEN cur; FETCH cur INTO temp_id; WHILE done <> 1 DO delete tree_test WHERE id = temp_id or parent_id = temp_id; FETCH cur INTO temp_id; END WHILE; CLOSE cur; END
这个就是执行的删除操作,基本的游标循环操作,话说这写法好像很有shell和python的韵味。proc1和proc2两个分别执行就可已,当然为了对外的友好,可以再写一个进行统一调用:
REATE DEFINER=`root`@`localhost` PROCEDURE `tree_test_query`(IN top int) BEGIN call proc1(top); call proc2(); END
三、第三种是我首先想到的,后来发现原来一般情况下会首先想到第二种,于是我觉得我确实懒的不行了。第三种方法实际就是第二种方法的偷懒方式,把所有的都放在一个存储过程中实现,实际SQL如下:
CREATE DEFINER=`root`@`localhost` PROCEDURE `tree_test_query`(IN top int) BEGIN DECLARE done INT DEFAULT 0; DECLARE temp_id INT; DECLARE cur CURSOR for( SELECT id from tree_test_view); DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; DROP VIEW IF EXISTS tree_test_view; SET @sqlstr = "CREATE VIEW tree_test_view as "; SET @sqlstr = CONCAT(@sqlstr , "SELECT id FROM tree_test WHERE parent_id = 0 LIMIT ", top); PREPARE stmt FROM @sqlstr; EXECUTE stmt; DEALLOCATE PREPARE stmt; OPEN cur; FETCH cur INTO temp_id; WHILE done <> 1 DO DELETE FROM tree_test WHERE id = temp_id or parent_id = temp_id; FETCH cur INTO temp_id; END WHILE; CLOSE cur; END
评论
1 楼
wuyang528378
2015-08-17
这样的方法的却能解决动态传参的问题,但是在并发访问时会有问题,多个线程操作同一个试图肯定有问题,所以视图的名字也需要动态变化保证不重复,这样一来,试图的名字也是一个变量,问题又回到原点了。
发表评论
-
MySQLdump增量备份、完全备份与恢复
2013-07-09 20:03 1765在数据库表丢失或损坏的情况下,备份你的数据库是很重要的。如果发 ... -
myisam表修复---check/repair
2013-06-30 21:53 1392myisam表修复---check/repair ... -
MySQL 性能跟踪语句
2013-06-25 12:15 987http://www.cnblogs.com/cy163/ar ... -
SQL海量数据优化
2013-06-05 11:36 1019具体要注意的: 1.应尽量避免在 where 子句中对字段进 ... -
Show processlist 状态分析
2013-05-27 13:39 1032Θ Sleep状态 √ 通常代表资源未释放,如果是通过连接池, ... -
mysqldump 临时备份避免锁表
2013-05-18 16:10 1666命令如下: mysqldump -u[用户名 ... -
Mysql show status命令
2013-05-16 11:08 958命令: show status; Aborted_clie ... -
Mysql 慢查询
2013-04-28 17:55 1346#定义超过1秒的查询计数到变量Slow_queries。 l ... -
Mysql 读写分离
2013-04-26 18:24 1603Mysql数据库读写分离 一、 Mysql数据库安装(此 ... -
Mysql 监控执行速度慢的语句
2013-03-29 08:34 1396首先,需要开启一个慢查询输出的一个机关:log_slow_qu ... -
mysql存储过程中用变量做表名
2013-03-26 10:28 3362mysql存储过程中用变量做表名 1.用变量做表名: 简单 ... -
Mysql 存储过程处理动态参数
2013-03-26 10:20 1223--删除 drop procedure if ex ... -
Mysql 常用函数
2012-11-21 11:45 0今天利用一点空闲时间,为大家整理一些Mysql的常用函数。当然 ... -
Mysql分表和分区的区别
2012-08-22 11:21 1299一,什么是mysql分表, ... -
Mysql分区
2012-08-22 13:27 955一,什么是数据库分区 前段时间写过一篇关于mysql分表的的 ... -
Mysql分表的三种方式
2012-08-22 13:27 1005一,先说一下为什么要 ... -
浅析Mysql的my.ini文件
2012-08-21 16:51 1306转载请注明:http://hunanpengdake.itey ... -
mysql日志的使用
2012-08-21 12:01 1056mysql有以下几种日志: 错误日志: -log-err 查询 ... -
解析Mysql数据恢复
2012-08-21 11:30 1018MYSQL数据库毁坏发生的原因有许多,且程度各不相同。如果幸运 ... -
Mysql失效后的数据恢复
2012-08-21 10:51 1064本篇文章用于一些特殊情况下,Mysql数据库失效,而数据无法正 ...
相关推荐
### MySQL游标(循环操作) #### 一、游标简介 在MySQL中,游标是一种数据库对象,主要用于处理存储过程中的结果集。游标允许我们逐行地读取查询结果,这对于需要对每一行数据执行特定操作的情况非常有用。通过...
MySQL游标是数据库管理系统中一个重要的概念,它在处理大量数据时非常有用,尤其是在需要逐行处理查询结果的情况下。游标允许程序动态地访问和操作数据集,而不是一次性加载所有结果。在MySQL中,游标主要用于存储...
在 MySQL 中,游标的使用和 PL/SQL 有点不同,但基本思想是一样的。游标可以用来实现复杂的数据处理逻辑,例如循环、判断、异常处理等。 在使用游标时,需要注意错误处理。在 MySQL 中,可以使用 CONTINUE HANDLER ...
而“源码”标签可能暗示了博文中会包含一些示例代码来展示如何在应用程序中(可能是使用Java、Python或其他语言)操作MySQL游标。 由于缺少具体博文内容,以上内容是基于对MySQL游标基本概念的解释,若要获取更详细...
MySQL游标是数据库管理系统中的一个重要概念,主要用于在存储过程或函数中逐行处理查询结果集。游标允许程序按需一次处理一行数据,而非一次性获取所有数据,这在处理大量数据时尤其有用,因为它可以避免一次性加载...
根据提供的文件信息,本文将详细解释一个MySQL存储过程的例子,其中包含了游标的使用。这个存储过程主要用于处理一批数据,涉及到日期范围内的数据处理、异常处理等。下面将逐一解析存储过程中涉及的重要知识点。 #...
本文档旨在介绍 MySQL 游标嵌套的概念和实践,通过对游标的嵌套使用,演示如何实现复杂的数据操作。 一、游标嵌套简介 游标(Cursor)是数据库中的一种控制结构,可以用来遍历查询结果集。游标嵌套则是指在一个...
本文旨在深入探讨MySQL中游标的概念及其使用方法,帮助读者更好地理解和掌握游标在实际开发中的应用。 #### 二、游标概述 ##### 2.1 游标的基本概念 游标是数据库系统中的一个重要概念,它可以理解为一种可以从包含...
以上就是MySQL游标的定义、使用和关闭的基本概念以及如何处理游标循环的细节。理解这些概念对于编写涉及复杂数据处理的存储过程至关重要。记住,游标虽然提供了逐行处理数据的能力,但也需要注意性能影响,因为它们...
MySQL游标是数据库管理系统提供的一种机制,允许程序按需逐行处理查询结果,而不是一次性获取所有数据。在大型数据集处理或需要分步执行复杂逻辑时,游标尤其有用。以下是对MySQL游标概念和用法的详细解释: 1. **...
MySQL游标是数据库管理系统中的一种机制,允许程序逐行处理查询结果集,而不是一次性加载所有数据。这在处理大量数据或者需要逐行处理结果时非常有用。游标提供了向前、向后滚动的能力,使得开发人员可以按需读取、...
使用游标时,可以检查`@@FETCH_STATUS`变量判断是否还有更多行可取。如果还有,可以继续使用`FETCH NEXT`,或者使用`WHERE CURRENT OF`更新当前行,甚至执行`DELETE`删除当前行。 4. **关闭和释放游标**: 完成...
在MySQL中使用游标涉及到几个关键步骤: **2.1 声明游标** ```sql DECLARE cursor_name CURSOR FOR SELECT statement; ``` 这里`cursor_name`是你给游标起的名字,`SELECT statement`是你想要执行的查询语句。 **...
在本示例中,我们将深入探讨如何在MySQL中使用动态游标,特别是结合存储过程来实现这一功能。 首先,创建了一个名为`webuser`的测试表,用于存放用户名数据。接着插入了一些示例数据,包括以'a'和'b'开头的用户。这...
For 循环游标隐式打开游标,自动滚动获取一条记录,并自动创建临时记录类型变量存储记录。处理完后自动关闭游标。While 循环游标需要手动打开和关闭游标,并使用 Fetch 语句获取记录。 在实际应用中,游标可以用于...
3. **读取数据**:使用`FETCH`语句从游标中读取数据行,通常与`INTO`子句结合使用,将数据加载到变量中。 ```sql FETCH c_emp INTO r_emp; ``` 4. **循环读取**:使用循环结构如`LOOP`,结合`EXIT WHEN`条件...