----------------SQL游标应用-----------------

今天由于业务需求,需要在存储过程中实现有一个表的主键去匹配在另一个表中作为外键所对应的数值

,若在C#中则非常简单只需要用两个for循环就可实现,但是在存储过程中时无法使用for循环的,于是想

到了使用游标来实现。

下面通过一个例子来介绍如何使用游标:

----------创建临时表------------

  1. if object_id('tempdb..#test0001') is not null drop table #test0001---------物料临时表
  2. create table #test0001(ItemCode nvarchar(30)----物料代码
  3.             ,SL DEC(19,3)----物料所需数量
  4.             ,RowsID Bigint----用于循环物料
  1. primary key(ItemCode)
  1.             )
  2. if object_id('tempdb..#test0002') is not null drop table #test0002---------容器临时表
  3. create table #test0002(Carton nvarchar(30)----容器代码
  4.             ,ItemCode nvarchar(30)----物料代码
  5.             ,CSL nvarchar(30)----容器里物料数量
  6.             ,RowsID Bigint ----用于循环容器,相同物料不同的容器进行排序
  1. primary key(Carton,ItemCode)
  1.             )
  2. if object_id('tempdb..#test0003') is not null drop table #test0003---物料在各个容器中最终要的数量表
  3. create table #test0003(ItemCode nvarchar(30)
  4.             ,CarTon nvarchar(30)
  5.             ,LastSL DEC(19,3)---在容器上所得数量
  6.             )

------------------向临时表中插入数据----------------

  1. insert into #test0001(ItemCode,SL,RowsID)
  2.       values('A',5,1),('B',10,2)---添加物料AB所需数量分别为510个,并给予物料排序
  3.  
  4. insert into #test0002(Carton,ItemCode,CSL,RowsID)
  5.       values('Q','A',3,1),('T','A',5,2),('Q','B',5,1) ,('T','B',3,2),('S','B',5,3)---给容器添加物料以及数量并给予物料所在不同容器排序
  6.       -----此时容器里的物料数为Q---A----3
  7.       -------------------------T---A----5
  8.       -------------------------Q---B----5
  9.       -------------------------T---B----3
  10.       -------------------------S---B----5
  11.  
  12.       -----则此时A物料在Q中获取3个、在T中取2
  13.       -----B物料在Q中取5个、在T中取3个、在S中取2

--------------定义临时变量与游标---------------

  1. declare @total_SL DEC(19,3)----临时物料总数量
  2. declare @CT_SL DEC(19,3)----临时容器物料数量
  3. declare @SL DEC(19,3)----临时物料数量
  4.  
  5. declare @test_cursor cursor------建立游标变量
  6. declare @test_rowid bigint-------作为匹配游标变量

-------------游标应用开始--------

  1. set @test_cursor = cursor for select RowsID from #test0001 ----设置游标绑定列
  2.  
  3. open @test_cursor--开启游标
  4.  
  5. fetch next from @test_cursor into @test_rowid--取第一个游标
  6.  
  7. while @@FETCH_STATUS = 0 ---一级循环
  8. begin
  9.  
  10.   --循环主体
  11.   select top 1
  12.   @total_SL = temp01.SL
  13.   from #test0001 temp01
  14.   where temp01.RowsID = @test_rowid
  15.   declare @test_cursor2 cursor
  16.   declare @test_rowid2 bigint
  17.  
  18.   set @test_cursor2 = cursor for select temp02.RowsID --设置游标绑定列;此游标是在容器表中按相同物料不同容器进行排序的
  19.   from #test0002 temp02
  20.   inner join #test0001 temp01 on temp01.ItemCode=temp02.ItemCode
  21.   where temp01.RowsID=@test_rowid
  22.  
  23.   --开启游标
  24.   open @test_cursor2
  25.   --取第一个游标
  26.   fetch next from @test_cursor2 into @test_rowid2
  27.  
  28.   while @@FETCH_STATUS = 0 ------二级循环
  29.   begin
  30.     select top 1
  31.     @CT_SL = temp02.CSL
  32.     from #test0002 temp02
  33.     inner join #test0001 temp01 on temp01.ItemCode=temp02.ItemCode
  34.     where temp02.RowsID = @test_rowid2
  35.     and temp01.RowsID = @test_rowid
  36.  
  37.     IF @CT_SL<@total_SL
  38.     begin -----若容器中存货量小于物料总数量则取完容器内数量
  39.     set @SL = @CT_SL
  40.     set @total_SL = @total_SL-@SL
  41.   end
  42.   else
  43.   begin
  44.     set @SL = @total_SL
  45.     set @total_SL = 0
  46.   end
  47.  
  48.   -------------将循环每条记录插入#test0003表中-----------
  49.   insert into #test0003(ItemCode
  50.              ,CarTon
  51.              ,LastSL
  52.              )
  53.         select temp01.ItemCode
  54.             ,temp02.Carton
  55.             ,@SL
  56.         from #test0001 temp01
  57.         inner join #test0002 temp02 on temp02.ItemCode=temp01.ItemCode
  58.         where temp01.RowsID=@test_rowid
  59.            and temp02.RowsID=@test_rowid2
  60.  
  61.         if @total_SL = 0 break;
  62.         --循环取游标下一个值
  63.         fetch next from @test_cursor2 into @test_rowid2
  64.       end
  65.       close @test_cursor2 --关闭二级游标
  66.       deallocate @test_cursor2 --关闭二级游标
  67.  
  68.       --循环取游标下一个值
  69.       fetch next from @test_cursor into @test_rowid
  70. end
  71. close @test_cursor--关闭一级游标
  72. deallocate @test_cursor--关闭一级游标

结果:

  1. select * from #test0001;

  1. select * from #test0002;

  1. select * from #test0003;

总结:
SQL 的游标类似于C程序里的for循环,上面的例子相当于C程序中的冒泡排序,SQL游标适用于存储过程中一张表需要循环匹配另一张表时用游标比较方便。

SQL Server 游标的应用的更多相关文章

  1. SQL Server 游标运用:鼠标轨迹字符串分割

    一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 游标模板(Cursor Template) 鼠标轨迹字符串分割SQL脚本实现(SQL Code ...

  2. sql server 游标的简单用法

    sql server游标: --定义游标 declare cursor1 cursor for select ID,Name from A --打开游标 open cursor1 declare @i ...

  3. SQL Server游标 C# DataTable.Select() 筛选数据 什么是SQL游标? SQL Server数据类型转换方法 LinQ是什么? SQL Server 分页方法汇总

    SQL Server游标   转载自:http://www.cnblogs.com/knowledgesea/p/3699851.html. 什么是游标 结果集,结果集就是select查询之后返回的所 ...

  4. SQL Server 游标运用:查看所有数据库所有表大小信息(Sizes of All Tables in All Database)

    原文:SQL Server 游标运用:查看所有数据库所有表大小信息(Sizes of All Tables in All Database) 一.本文所涉及的内容(Contents) 本文所涉及的内容 ...

  5. SQL Server 游标运用:查看一个数据库所有表大小信息(Sizes of All Tables in a Database)

    原文:SQL Server 游标运用:查看一个数据库所有表大小信息(Sizes of All Tables in a Database) 一.本文所涉及的内容(Contents) 本文所涉及的内容(C ...

  6. SQL Server游标(转)

    清晰地介绍了SQL游标,很好的学习资料. 转自 http://www.cnblogs.com/knowledgesea/p/3699851.html 什么是游标 结果集,结果集就是select查询之后 ...

  7. SQL Server游标

    什么是游标 结果集,结果集就是select查询之后返回的所有行数据的集合. 游标则是处理结果集的一种机制吧,它可以定位到结果集中的某一行,多数据进行读写,也可以移动游标定位到你所需要的行中进行操作数据 ...

  8. SQL Server游标【转】

      什么是游标 结果集,结果集就是select查询之后返回的所有行数据的集合. 游标则是处理结果集的一种机制吧,它可以定位到结果集中的某一行,多数据进行读写,也可以移动游标定位到你所需要的行中进行操作 ...

  9. SQL Server 游标

    结果集,结果集就是select查询之后返回的所有行数据的集合. 在关系数据库中,我们对于查询的思考是面向集合的.而游标打破了这一规则,游标使得我们思考方式变为逐行进行. 正常面向集合的思维方式是: 而 ...

  10. SQL SERVER 游标的使用

    首先,关于什么是游标大家可以看看这篇文章,介绍得非常详细!! SQL Server基础之游标 下面是我自己的应用场景-- 有个需求,需要把数据库表里面某一个字段的值设为随机不重复的值. 表是这样的: ...

随机推荐

  1. birt启动后访问地址详解

    发布设计完成的报表文件,可在web项目中创建reports目录,用于存放报表设计文件. 在应用中通过正确格式的访问路径,例如:http://localhost:8080/birtApp/framese ...

  2. JDBC连接数据以及详细的ResultSet结果集解释

    一.数据库连接 (前面为jdbc的其他参数,文章下部分为ResultSet详解) ResultSet rs = st.executeQuery(sqlStr) 1. java的sql框架支持多种数据库 ...

  3. CC34:判断直线相交

    题目 解法 水题,判断斜率.判断截距,ok..... class CrossLine { public: bool checkCrossLine(double s1, double s2, doubl ...

  4. easyui---datalist相关知识

    datalist 笔记: class:class="easyui-datalist" //对应标准元素:ul 表格线:lines="true" 远程数据绑定: ...

  5. Codeforces Round #375 (Div. 2) D. Lakes in Berland 并查集

    http://codeforces.com/contest/723/problem/D 这题是只能把小河填了,题目那里有写,其实如果读懂题这题是挺简单的,预处理出每一块的大小,排好序,从小到大填就行了 ...

  6. feign实现服务间的负载均衡

    feign Feign是一个声明式的Web Service客户端,它使得编写Web Serivce客户端变得更加简单.我们只需要使用Feign来创建一个接口并用注解来配置它既可完成.它具备可插拔的注解 ...

  7. IDEA SpringBoot +thymeleaf配置

    1.pom添加以下依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactI ...

  8. vuejs 学习旅程一

    来上海快一年了,一直在东钿金融工作着,这一年来主要负责公司前期的房产评估微信平台,公司IT部也是刚刚成立,成立IT部门不仅仅只是维护房产评估微信,而是要做一个互金理财平台.于是我一年来的主要工作是负责 ...

  9. GoDaddy网站程序根目录 网站文件上传到虚拟主机哪个目录

    用的linux虚拟主机,网站根目录为public_html,(window主机的目录为httpdocs)我们需要把本地做好的网站上传到此目录下 cPanel控制面板 - 文件管理器 - public_ ...

  10. 小目标 | DAX高级实践-Power BI与Excel联合应用

    · 适用人群:数据分析专业人士,在数据分析方向需求发展人士 · 应用场景:数据汇报.数据可视化展现.数据建模分析 · 掌握难度:★★★★☆ 本期讲师 DAX高级实践-Power BI与Excel联合应 ...