原文:【Transact-SQL】让人快遗忘的游标


最初学SQL Server的时候,当学到游标的时候,突然有了一种亲切感,因为这种通过一个while循环,一条一条的处理数据的方式,很像学过的过程式语言,与C语言很相似。

慢慢的,对一些稍微复杂一点的SQL ,往往就会想到用游标去处理。也正是因为大量使用,渐渐的,在使用的过程中,也真正体会到了游标的低效,一条一条的处理方式,在数据量很小的情况下还可以,当数据一旦很多,而处理过程又非常复杂时,往往速度就会很慢。

于是乎,慢慢的开始放弃使用游标,最后都快忘记了这个老朋友了。

今天,在论坛突然发现有人提了一个问题,希望用游标来解决,于是乎,又让我再次想起了游标。

下面是那个网友提出的问题:


我有两张表,分别是:table1
 KHMC         SPDM DJ  SL XSSL
广西骆俊峰 5609B 100.0000 12 NULL
广西骆俊峰 5609B 80.0000  7 NULL
广西骆俊峰 5609B 60.0000  6 NULL
广西骆俊峰 5609B 50.0000  13 NULL
广西骆俊峰 5609B 40.0000  21 NULL
table2
khmc         spdm sl bysl
广西骆俊峰 5609B 20 NULL

而我想要的结果是用第二张表里的数据去一行行的填充第一个表的数据(关联关系是 khmc,spdm):
 KHMC         SPDM DJ  SL XSSL
广西骆俊峰 5609B 100.0000 12 12
广西骆俊峰 5609B 80.0000  7 7
广西骆俊峰 5609B 60.0000  6 1
广西骆俊峰 5609B 50.0000  13 NULL
广西骆俊峰 5609B 40.0000  21 NULL

首先是建表语句:


  1. create table table1
  2. (KHMC varchar(20), SPDM varchar(10), DJ varchar(10), SL int, XSSL int)
  3. insert into table1
  4. select '广西骆俊峰', '5609B', '100.0000', 12, null union all
  5. select '广西骆俊峰', '5609B', '80.0000', 7, null union all
  6. select '广西骆俊峰', '5609B', '60.0000', 6, null union all
  7. select '广西骆俊峰', '5609B', '50.0000', 13, null union all
  8. select '广西骆俊峰', '5609B', '40.0000', 21, null
  9. create table table2
  10. (khmc varchar(20), spdm varchar(10), sl int, bysl int)
  11. insert into table2
  12. select '广西骆俊峰', '5609B', 20, null

然后是游标代码,是嵌套的游标,外层游标内还有一个游标:


  1. declare @table1_khmc varchar(10)
  2. declare @table1_spdm varchar(20)
  3. declare @table1_sl int
  4. declare @table1_xssl int
  5. --定义table1的游标
  6. declare cur_table1 cursor
  7. for select KHMC,SPDM,sl,xssl from table1 for update --可以游标更新的
  8. declare @table2_khmc varchar(10)
  9. declare @table2_spdm varchar(20)
  10. declare @table2_sl int
  11. --定义table2的游标
  12. declare cur_table2 cursor
  13. for select khmc,spdm,sl from table2 --用于查询的游标
  14. open cur_table2; --打开游标
  15. --从游标中取数,放到变量中
  16. fetch next from cur_table2 into @table2_khmc,@table2_spdm,@table2_sl
  17. while @@FETCH_STATUS = 0 --外层游标cur_table2的遍历
  18. begin
  19. open cur_table1;
  20. fetch next from cur_table1 into @table1_khmc,@table1_spdm,@table1_sl,@table1_xssl
  21. while @@FETCH_STATUS = 0 --内存游标cur_table1的遍历
  22. begin
  23. if (@table1_khmc = @table2_khmc) and (@table2_spdm = @table1_spdm)
  24. begin
  25. update table1
  26. set xssl = case when @table2_sl >= isnull(@table1_sl,0)
  27. then @table1_sl
  28. when @table2_sl < isnull(@table1_sl,0)
  29. then @table2_sl
  30. end
  31. where current of cur_table1;
  32. --如果table2的sl大于table1的sl,那么可以继续循环,否则就退出内层有游标
  33. if @table2_sl >= isnull(@table1_sl,0)
  34. set @table2_sl = @table2_sl - ISNULL(@table1_sl,0);
  35. else
  36. break;
  37. fetch next from cur_table1 into @table1_khmc,@table1_spdm,@table1_sl,@table1_xssl
  38. end
  39. end
  40. close cur_table1; --关闭内层游标
  41. fetch next from cur_table2 into @table2_khmc,@table2_spdm,@table2_sl
  42. end
  43. close cur_table2; --关闭游标
  44. deallocate cur_table2; --释放游标cur_table2的资源
  45. deallocate cur_table1; --释放游标cur_table1的资源
  46. --查询更新后的结果
  47. select *
  48. from table1
  49. /*
  50. KHMC SPDM DJ SL XSSL
  51. 广西骆俊峰 5609B 100.0000 12 12
  52. 广西骆俊峰 5609B 80.0000 7 7
  53. 广西骆俊峰 5609B 60.0000 6 1
  54. 广西骆俊峰 5609B 50.0000 13 NULL
  55. 广西骆俊峰 5609B 40.0000 21 NULL
  56. */

发布了416 篇原创文章 · 获赞 135 · 访问量 94万+

【Transact-SQL】让人快遗忘的游标的更多相关文章

  1. StringBuilder 拼接sql语句比较快

    StringBuilder 拼接sql语句比较快StringBuilder strBuilder = new StringBuilder();strSql += "insert into t ...

  2. SQL Server 内存泄露(memory leak)——游标导致的内存问题

    原文:SQL Server 内存泄露(memory leak)--游标导致的内存问题 转自:http://blogs.msdn.com/b/apgcdsd/archive/2011/07/01/sql ...

  3. 静态分析第三发 so文件分析(小黄人快跑)

    本文作者:i春秋作家——HAI_ 0×00 工具 1.IDA pro 2.Android Killer 0×01 环境 小黄人快跑 下载地址http://download.csdn.net/downl ...

  4. 13Microsoft SQL Server SQL 高级事务,锁,游标,分区

    Microsoft SQL Server SQL高级事务,锁,游标,分区 通过采用事务和锁机制,解决了数据库系统的并发性问题. 9.1数据库事务 (1)BEGIN TRANSACTION语句定义事务的 ...

  5. SQL Server 事务、异常和游标

    转自:http://www.cnblogs.com/hoojo/archive/2011/07/19/2110325.html Ø 事务 在数据库中有时候需要把多个步骤的指令当作一个整体来运行,这个整 ...

  6. SQL Server 存储过程、触发器、游标

    存储过程 1.存储过程是事先编好的.存储在数据库中的程序,这些程序用来完成对数据库的指定操作. 2.系统存储过程: SQL Server本身提供了一些存储过程,用于管理有关数据库和用户的信息. 用户存 ...

  7. SQL server存储过程,触发器,游标相关实例

    use MySchool go alter proc P_stu as select AVG(StudentResult)as 平均分 from Result select * from Result ...

  8. SQL中什么时候需要使用游标?使用游标的步骤

    https://zhidao.baidu.com/question/568932670.html 例子table1结构如下id intname varchar(50) declare @id intd ...

  9. sql中多层循环示例(有游标)

    在需求处理中,我们会遇到需要通过SQL多层循环来处理的问题.如:A表中有8条数据,B表中有10条数据,需要实现A表中的每1条数据对应B表中的10条数据,最后就有了80条数据,从而实现一对多的关系.那如 ...

随机推荐

  1. 灵活使用ssh、dsh和pssh高效管理大量计算机

    http://os.iyunv.com/art/201012/240113.htm 灵活使用ssh.dsh和pssh高效管理大量计算机 http://os.iyunv.com2010-12-23 09 ...

  2. 【Oracle】创建用户及设定权限

    ; grant create session to ufo; grant create tablespace to ufo; grant create table to ufo; grant drop ...

  3. 阿里巴巴高可用技术专家襄玲:压测环境的设计和搭建 PTS - 襄玲 云栖社区 今天

    阿里巴巴高可用技术专家襄玲:压测环境的设计和搭建 PTS - 襄玲 云栖社区 今天

  4. Python 中的 -> 是什么意思

    函数标注通常用于 类型提示:例如以下函数预期接受两个 int 参数并预期返回一个 int 值:```def sum_two_numbers(a: int, b: int) -> int:retu ...

  5. websphere 英文版部署(更新)项目【我】

    websphere 部署(更新)项目 首先在控制台页面依次点左侧,打开应用配置页面: 然后在右侧勾选我们要重新部署的项目,首先点上面的 停止 按钮,等项目停止后,再勾选项目,点上面的  更新 按钮(如 ...

  6. OSG节点访问和遍历

    遍历节点树:osg::Node类中有两个辅助函数: void ascend(NodeVisitor& nv) //虚函数,向上一级节点推进访问器 void traverse(NodeVisit ...

  7. mybatis bind exception

    springboot  项目  搜了半天 网上的解决方法千篇一律,最终问题 原因 ,yml 文件路径问题 mybatis: mapper-locations: classpath:com/yang/f ...

  8. 123457123457#1#-----com.threeapp.ErTongHuaXue01----儿童滑雪大冒险

    123456123456#0#-----com.threeapp.ErTongHuaXue01----儿童滑雪大冒险

  9. spark的task调度器(FAIR公平调度算法)

    FAIR  调度策略的树结构如下图所示: FAIR 调度策略内存结构 FAIR 模式中有一个 rootPool 和多个子 Pool, 各个子 Pool 中存储着所有待分配的 TaskSetMagage ...

  10. Spring Boot使用过滤器Filter

    首先创建一个测试用的controller:TestController: package com.zifeiy.test.controller; import org.springframework. ...