原文:【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. office web apps 在线问答预览

    最近在做项目时,需要用到在线文档预览,看过明道的一篇搭建office web apps服务的文章,但是由于时间的关系,没有仔细研究,这几天有时间,就拿出来研究了下,折腾了几天终于完成了部署,然后就搬过 ...

  2. VS版本 与 VC版本 的对应关系

    Visual Studio 6 : vc6Visual Studio 2003 : vc7Visual Studio 2005 : vc8Visual Studio 2008 : vc9Visual ...

  3. Java使用jxl修改现有Excel文件内容,并验证其是否对公式的结果产生影响

    jxl的maven坐标: <!-- https://mvnrepository.com/artifact/net.sourceforge.jexcelapi/jxl --> <dep ...

  4. MongoDB集群之分片技术应用 —— 学习笔记

    课程链接:https://www.imooc.com/learn/501 一.什么是分片? 分片:将数据进行2拆分,将数据水平的分散到不同的服务器上. 二.为什么要分片? 架构上:读写均衡.去中心化 ...

  5. OpenGL学习笔记 之二 (色彩相关)

    参考: http://www.cnblogs.com/FredCong/archive/2012/10/13/2722893.html 使用RGB #include <glut.h> #i ...

  6. CardView的使用(可以实现圆角控件)

    简介:ardView继承自FrameLayout,它是一个带圆角背景和阴影的FrameLayout 一些什么实现方式就不赘述了,直接上用法 CardView的常用属性   1.设置背景颜色  app: ...

  7. js 数组去重、去空(收藏)

    function unique (arr) { return Array.from(new Set(arr)) } var arr = [1,1,'true','true',true,true,15, ...

  8. java枚举的线程安全及序列化

    原文链接:https://www.cnblogs.com/z00377750/p/9177097.html https://www.cnblogs.com/chiclee/p/9097772.html ...

  9. (模板)扩展kmp算法(luoguP5410)

    题目链接:https://www.luogu.org/problem/P5410 题意:有两个字符串a,b,要求输出b与a的每一个后缀的最长公共前缀.输出: 第一行有lenb个数,为b的next数组( ...

  10. java - redis学习

    在学习redis之前,我们首先需要了解一下NoSQL(非关系数据库).非关系型数据库通常指数据以对象的形式存储在数据库中,而对象之间的关系通过每个对象自身的属性来决定. 为什么需要NoSQL? (1) ...