【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
首先是建表语句:
create table table1
(KHMC varchar(20), SPDM varchar(10), DJ varchar(10), SL int, XSSL int)
insert into table1
select '广西骆俊峰', '5609B', '100.0000', 12, null union all
select '广西骆俊峰', '5609B', '80.0000', 7, null union all
select '广西骆俊峰', '5609B', '60.0000', 6, null union all
select '广西骆俊峰', '5609B', '50.0000', 13, null union all
select '广西骆俊峰', '5609B', '40.0000', 21, null
create table table2
(khmc varchar(20), spdm varchar(10), sl int, bysl int)
insert into table2
select '广西骆俊峰', '5609B', 20, null
然后是游标代码,是嵌套的游标,外层游标内还有一个游标:
declare @table1_khmc varchar(10)
declare @table1_spdm varchar(20)
declare @table1_sl int
declare @table1_xssl int
--定义table1的游标
declare cur_table1 cursor
for select KHMC,SPDM,sl,xssl from table1 for update --可以游标更新的
declare @table2_khmc varchar(10)
declare @table2_spdm varchar(20)
declare @table2_sl int
--定义table2的游标
declare cur_table2 cursor
for select khmc,spdm,sl from table2 --用于查询的游标
open cur_table2; --打开游标
--从游标中取数,放到变量中
fetch next from cur_table2 into @table2_khmc,@table2_spdm,@table2_sl
while @@FETCH_STATUS = 0 --外层游标cur_table2的遍历
begin
open cur_table1;
fetch next from cur_table1 into @table1_khmc,@table1_spdm,@table1_sl,@table1_xssl
while @@FETCH_STATUS = 0 --内存游标cur_table1的遍历
begin
if (@table1_khmc = @table2_khmc) and (@table2_spdm = @table1_spdm)
begin
update table1
set xssl = case when @table2_sl >= isnull(@table1_sl,0)
then @table1_sl
when @table2_sl < isnull(@table1_sl,0)
then @table2_sl
end
where current of cur_table1;
--如果table2的sl大于table1的sl,那么可以继续循环,否则就退出内层有游标
if @table2_sl >= isnull(@table1_sl,0)
set @table2_sl = @table2_sl - ISNULL(@table1_sl,0);
else
break;
fetch next from cur_table1 into @table1_khmc,@table1_spdm,@table1_sl,@table1_xssl
end
end
close cur_table1; --关闭内层游标
fetch next from cur_table2 into @table2_khmc,@table2_spdm,@table2_sl
end
close cur_table2; --关闭游标
deallocate cur_table2; --释放游标cur_table2的资源
deallocate cur_table1; --释放游标cur_table1的资源
--查询更新后的结果
select *
from table1
/*
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
*/
【Transact-SQL】让人快遗忘的游标的更多相关文章
- StringBuilder 拼接sql语句比较快
StringBuilder 拼接sql语句比较快StringBuilder strBuilder = new StringBuilder();strSql += "insert into t ...
- SQL Server 内存泄露(memory leak)——游标导致的内存问题
原文:SQL Server 内存泄露(memory leak)--游标导致的内存问题 转自:http://blogs.msdn.com/b/apgcdsd/archive/2011/07/01/sql ...
- 静态分析第三发 so文件分析(小黄人快跑)
本文作者:i春秋作家——HAI_ 0×00 工具 1.IDA pro 2.Android Killer 0×01 环境 小黄人快跑 下载地址http://download.csdn.net/downl ...
- 13Microsoft SQL Server SQL 高级事务,锁,游标,分区
Microsoft SQL Server SQL高级事务,锁,游标,分区 通过采用事务和锁机制,解决了数据库系统的并发性问题. 9.1数据库事务 (1)BEGIN TRANSACTION语句定义事务的 ...
- SQL Server 事务、异常和游标
转自:http://www.cnblogs.com/hoojo/archive/2011/07/19/2110325.html Ø 事务 在数据库中有时候需要把多个步骤的指令当作一个整体来运行,这个整 ...
- SQL Server 存储过程、触发器、游标
存储过程 1.存储过程是事先编好的.存储在数据库中的程序,这些程序用来完成对数据库的指定操作. 2.系统存储过程: SQL Server本身提供了一些存储过程,用于管理有关数据库和用户的信息. 用户存 ...
- SQL server存储过程,触发器,游标相关实例
use MySchool go alter proc P_stu as select AVG(StudentResult)as 平均分 from Result select * from Result ...
- SQL中什么时候需要使用游标?使用游标的步骤
https://zhidao.baidu.com/question/568932670.html 例子table1结构如下id intname varchar(50) declare @id intd ...
- sql中多层循环示例(有游标)
在需求处理中,我们会遇到需要通过SQL多层循环来处理的问题.如:A表中有8条数据,B表中有10条数据,需要实现A表中的每1条数据对应B表中的10条数据,最后就有了80条数据,从而实现一对多的关系.那如 ...
随机推荐
- PyTorch Tutorials 2 AUTOGRAD: AUTOMATIC DIFFERENTIATION
%matplotlib inline Autograd: 自动求导机制 PyTorch 中所有神经网络的核心是 autograd 包. 我们先简单介绍一下这个包,然后训练第一个简单的神经网络. aut ...
- linux内核是如何支持深度睡眠(deep sleep)方式的?
1. 硬件架构 arm64 2. 内核版本 4.19 3. 分析相关函数 setup_arch() -> psci_dt_init() -> psci_0_2_init() -> g ...
- CV3——学习笔记-续
使用Jupyter.https://jupyter.org/install https://baijiahao.baidu.com/s?id=1601883438842526311&wfr=s ...
- ubuntu更强大的包管理工具:aptitude
aptitude 与 apt-get 一样,是 Debian 及其衍生系统ubuntu上 一个强大的包管理工具.与 apt-get 不同的是,aptitude 在处理依赖问题上更佳一些.apt ...
- 阶段5 3.微服务项目【学成在线】_day18 用户授权_07-动态查询用户权限-权限数据模型
3 动态查询用户权限 3.1 需求分析 截至目前在测试授权时使用的权限数据是静态数据,正常情况的流程是: 1.管理员给用户分配权限,权限数据写到数据库中. 2.认证服务在进行用户认证时从数据库读取用户 ...
- 算法习题---3.08循环小数(UVa202)
一:题目 输入整数a和b(<=a<=,<=b<=),输出a/b的循环小数表示以及循环节长度. 例如,a=,b=,小数表示为0.(),循环字节长度为21 当循环节长度超过50时, ...
- UIFontDownLoad ----动态下载系统提供的字体
程序运行结果如下 : 当点击对应单元格实现下载对应的字体. 控制台打印结果如下 : 2015-10-05 11:14:04.132 UIFontDownLoad[12721:86827] state ...
- 为什么要用k8s
经过几次面试,发现有的公司没有用过k8s,有的公司正在用,但是都问了共同的问题:k8s的好处在哪里.所以总结了一下几点 1.故障迁移:当某一个node节点关机或挂掉后,node节点上的服务会自动转移到 ...
- 浅出讲解:php的socket通信
原文地址:https://www.cnblogs.com/aipiaoborensheng/p/6708963.html 对TCP/IP.UDP.Socket编程这些词你不会很陌生吧?随着网络技术的发 ...
- 【谷歌浏览器】修改和添加Cookie
一.使用谷歌浏览器 1.1.修改ookie 方法一:直接用开发者工具修改: 操作如图: 参考: 检查和删除 Cookie · Chrome 开发者工具中文文档 http://www.css88.c ...