mysql 游标使用动态变量

从语法上来讲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驱动的话,貌似不太现实,于是考虑其它方式。我总结一下解决这个问题有三种途径。

一、避免使用动态游标的可能性。首先使用所谓动态就是一段代码可复用与多种情况,于是每种情况都写一种代码就可避免,但是作为开发人员,基本没人会这样做。

二、拆分存储过程。假设存在表结构如下:

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)

1

mysql>desctree_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||+———–+————-+——+—–+———+—————-+3rowsinset(0.00sec)

欢迎大家阅读《Mysql 游标施用动态变量》,跪求各位点评,by 搞代码

现在的问题就是将不确定值传给游标,简单的游标定义如下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

1

CREATEDEFINER=`root`@`localhost`PROCEDURE`proc1`(INtopint)BEGINDROPVIEWIFEXISTStree_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);PREPAREstmtFROM@sqlstr;EXECUTEstmt;DEALLOCATEPREPAREstmt;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

1

CREATEDEFINER=`root`@`localhost`PROCEDURE`proc2`()BEGINDECLAREdoneINTDEFAULT0;DECLAREtemp_idINT;DECLAREcurCURSORfor(SELECTidfromtree_test_view);DECLARECONTINUEHANDLERFORNOTFOUNDSETdone=1;OPENcur;FETCHcurINTOtemp_id;WHILEdone<>1DOdeletetree_testWHEREid=temp_idorparent_id=temp_id;FETCHcurINTOtemp_id;ENDWHILE;CLOSEcur;END

这个就是执行的删除操作,基本的游标循环操作,话说这写法好像很有shell和python的韵味。proc1和proc2两个分别执行就可已,当然为了对外的友好,可以再写一个进行统一调用:

REATE DEFINER=`root`@`localhost` PROCEDURE `tree_test_query`(IN top int) BEGIN call proc1(top); call proc2(); END

1

REATEDEFINER=`root`@`localhost`PROCEDURE`tree_test_query`(INtopint)BEGINcallproc1(top);callproc2();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

CREATEDEFINER=`root`@`localhost`PROCEDURE`tree_test_query`(INtopint)BEGINDECLAREdoneINTDEFAULT0;DECLAREtemp_idINT;DECLAREcurCURSORfor(SELECTidfromtree_test_view);DECLARECONTINUEHANDLERFORNOTFOUNDSETdone=1;DROPVIEWIFEXISTStree_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);PREPAREstmtFROM@sqlstr;EXECUTEstmt;DEALLOCATEPREPAREstmt;OPENcur;FETCHcurINTOtemp_id;WHILEdone<>1DODELETEFROMtree_testWHEREid=temp_idorparent_id=temp_id;FETCHcurINTOtemp_id;ENDWHILE;CLOSEcur;END

原创文章,转载请注明: 转载自搞代码

微信 赏一包辣条吧~

支付宝 赏一听可乐吧~

mysql 游标动态传参数_Mysql 游标施用动态变量相关推荐

  1. MySQL函数少传参数_Mysql中的少用函数

    1.查询时需要转换类型,大多发生在数字和字符串.时间和字符串之间 Mysql提供了两个个类型转换函数:CAST和CONVERT CAST() 和CONVERT() 函数可用来获取一个类型的值,并产生另 ...

  2. oracle 游标当方法参数,Oracle游标、参数的使用例子

    /// /// 总部审核 /// /// /// public int Update(Hashtable ht) { //修改 StringBuilder sb = new StringBuilder ...

  3. uploadify 3.2 后台动态传参数

    最近在弄一个上传的小功能,需要往后台传递一些动态参数,网上有一些传参数可能是因为版本不对也没成功.仔细看了官网的一些说明,搞定了. 3.2中传递参数用的的是'formData':{'somekey': ...

  4. mysql 游标总条数_mysql 游标的使用总结

    一.游标的基本概念 游标:游标是一个存储在Mysql服务器上的数据库查询,它不是一条select语句,而是被该语句检索出来的结果集. 本人,学习游标中,曾遇到一个问题,循环总是最后多执行一次.下面分析 ...

  5. mysql几个timeout参数_MySQL中 timeout相关参数解析

    前言: MySQL中有两个关于连接超时的配置项.他们之间在某些条件下会互相继承,那究竟这两个参数会在什么情况下起作用呢? 本文将会通过一些测试实例来证明总结两者的相互关系. 参数介绍: The num ...

  6. mysql批量插入 增加参数_MySql 的批量操作,要加rewriteBatchedStatements参数

    MySql 的批量操作,要加rewriteBatchedStatements参数 作者:赵磊 博客:http://elf8848.iteye.com ------------------------- ...

  7. mysql数据库密码安全参数_MySQL 密码参数配置与修改 validate_password

    MySQL 密码参数配置与修改 validate_password 场景 通过root用户创建travel_agency数据库,目标是,新建一个用户然后对仅对该用户开放travel_agency数据库 ...

  8. mysql执行动态说起来_MySQL实战45讲学习笔记:第十四讲

    一.引子 在开发系统的时候,你可能经常需要计算一个表的行数,比如一个交易系统的所有变更记录总数.这时候你可能会想,一条 select count(*) from t 语句不就解决了吗? 但是,你会发现 ...

  9. mysql自定义函数多参数_MySQL数据库高级(二)——自定义函数

    MySQL数据库高级(二)--自定义函数 一.自定义函数简介 自定义函数 (user-defined function UDF)是一种对MySQL扩展的途径,其用法和内置函数相同. 自定义函数的两个必 ...

  10. mysql如何上传照片_MySQL数据库之图片上传存储数据库的2种方法讲解(Mysql)

    本文主要向大家介绍了MySQL数据库之图片上传存储数据库的2种方法讲解(Mysql) ,通过具体的内容向大家展现,希望对大家学习MySQL数据库有所帮助. 数据库Mysql存储,读取图片 在项目中,很 ...

最新文章

  1. 栈区和堆区内存分配区别
  2. python入门爬虫知识点
  3. stylelint初体验
  4. vue踩坑- 报错npm ERR! cb() never called!
  5. 干货!不得不知的UI界面中“行为召唤按钮”设计秘诀
  6. html标签table的使用,HTML标签之table
  7. 洗礼灵魂,修炼python(54)--爬虫篇—urllib2模块
  8. python进行数据分析
  9. AWK 之 RS、ORS与FS、OFS
  10. Winform控件学习笔记【第四天】——WebBrowser
  11. php中的分页类Page的用法
  12. ASP.NET Core的路由[2]:路由系统的核心对象——Router
  13. 个人或公司微信公众号迁移转让流程,公证需要资料,订阅号服务号转移教程,怎么迁移
  14. 【Flutter小记9】flutter 打包的apk在某些真机无法安装或打开
  15. android之ExoPlayer探索
  16. RPO和RTO是什么?
  17. 视觉SLAM十四讲 ch3 (三维空间刚体运动)笔记
  18. f下行到什么形成全音_乐理试题二
  19. 阿里架构师谈:工作三年的Java程序员应该达到什么水平?
  20. 因果推断笔记——CV、机器人领域因果推断案例集锦(十)

热门文章

  1. 基于卷积神经网络和迁移学习实现场景图片分类任务
  2. IplImage 加载图像
  3. BOOL与bool区别
  4. java switch finally_Java中的switch疑问
  5. python string 编解码(encode b64encode)
  6. 从照相机到jpeg的流程中分析图像噪声
  7. DPDK-VPP 学习笔记-04 Load Balancer plugin nat4 PATCH
  8. Linux系统之下的基本gdb调试
  9. 如何配置RadASM
  10. 在微信公众号中写html代码吗,微信公众号代码编写怎么做