原文:【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. A filter or servlet of the current chain does not support asynchronous operations. 错误解决记录

    做视频文件上传一直报这个错误: java.lang.IllegalStateException: A filter or servlet of the current chain does not s ...

  2. 亲历谷歌 Chrome 浏览器弹窗境外广告的解决方法(图) | 技术乐园

    亲历谷歌 Chrome 浏览器弹窗境外广告的解决方法(图) | 技术乐园 转 https://www.hack520.com/338.html 谷歌的 Chrome 浏览器是我非常喜欢的一款的浏览器, ...

  3. IDEA 不编译java以外的文件

    解决办法:修改pom 文件 <build> <resources> <resource> <directory>src/main/java</di ...

  4. Docker安装LogonTracer

    LogonTracer LogonTracer:是一款用于可视化分析Windows安全事件日志寻找恶意登录的工具.它会将登录相关事件中找到的主机名(或IP地址)和帐户名称关联起来,并将其以图形化的方式 ...

  5. Docker 容器的运行(八)

    目录 一.运行容器 1.运行第一个容器 2.让容器长期运行 二.进入容器 1.attach 2.exec 3.attach VS exec 4.容器内部都在干些什么 三.停止/启动/重启容器 四.暂停 ...

  6. 最新 游族网络java校招面经 (含整理过的面试题大全)

    从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.游族网络等10家互联网公司的校招Offer,因为某些自身原因最终选择了游族网络.6.7月主要是做系统复习.项目复盘.Leet ...

  7. cocos creator 倒计时code

    let countDownNode = this.viewNode.getChildByName('countDownNode').getComponent(cc.Label); countDownN ...

  8. 【leetcode算法-中等】2. 两数相加

    [题目描述] 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表 ...

  9. uwp,右键浮出获取DataContext(数据上下文)

    列表视图类控件,如ListView/GridView,有时项目需要按下右键浮出选项,来获取Item的DataContext. 下面的示例代码,事先我已经有了一个自定义类Video,并且已经绑定了数据源 ...

  10. v-if v-else-if v-else 条件渲染案例

    <body><!--修饰符--><div id="app"> <span v-if="isuser"> < ...