原文:【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. P5658 括号树

    P5658 括号树 题解 太菜了啥都不会写只能水5分数据 啥都不会写只能翻题解  题解大大我错了 我们手动找一下规律 我们设 w[ i ] 为从根节点到结点 i 对答案的贡献,也就是走到结点 i ,合 ...

  2. Centos7.4服务器安装Laravel5.7详细讲解(2018-10-27)

    一.在阿里云或者腾讯云选择Centos7并购买服务器 二.安装宝塔面板和php运行环境 1.输入命令 yum install -y wget && wget -O install.sh ...

  3. linux下程序启动后后台运行实现

    关于linux下的程序运行很简单,将源码编译成二进制(假设为proram)文件后直接在命令行运行即可,root#./program如果需要后台运行,即不占用当前终端,这在嵌入式linux显得十分有必要 ...

  4. 整理Mac系统 node-sass 安装失败的原因及解决办法

    转载与:https://segmentfault.com/a/1190000010984731 声明:本文非原创,如有侵权请留言或发邮件告知,作者会立即停止侵权并删除本文.发布此文章主要是希望跟作者遇 ...

  5. 123457123457#1#-----com.threeapp.circlerunner01----儿童旋转跑酷游戏

    com.threeapp.circlerunner01----儿童旋转跑酷游戏

  6. VL10B 采购订单转DN

    传入采购订单项目建交货单 FUNCTION zmmfmXXXX. *"------------------------------------------------------------ ...

  7. ElasticSearch——原始文档和倒排索引

    一.原始文档 如上图所示, 第二象限是一份原始文档,有title和content2个字段,字段取值分别为”我是中国人”和” 热爱共X产党”,这一点没什么可解释的.我们把原始文档写入Elasticsea ...

  8. MySQL中创建存储过程示例

    在这个示例中需要用到一张名为test_table的表,我们使用show create table test_table查看表的创建过程: CREATE TABLE `test_table` ( `id ...

  9. 移动App书写Test Case时需要考虑的检查点

    在测试工作中我们需要不断的总结和储备自己的知识和经验,譬如具备特定属性.环境以及场景,如:PC,手机,智能设备,特定网络环境下. 我们需要关注的功能点,容易出错的位置,这将对我们整个测试过程起至关作用 ...

  10. UiPath工具当中写入代码

    在UIPath的工具中选择下面的控件 点击[Edit Code]之后出现写代码的地方,入力VB.net代码 点击[Edit Arguments]之后是这个方法的传入和传出的值. 下面自己做的一个小例子 ...