1    什么是游标:

关系数据库中的操作会对整个行集起作用。 例如,由 SELECT 语句返回的行集包括满足该语句的 WHERE 子句中条件的所有行。 这种由语句返回的完整行集称为结果集。 应用程序,特别是交互式联机应用程序,并不总能将整个结果集作为一个单元来有效地处理。 这些应用程序需要一种机制以便每次处理一行或一部分行。 游标就是提供这种机制的对结果集的一种扩展。

游标通过以下方式来扩展结果处理:

  • 允许定位在结果集的特定行。
  • 从结果集的当前位置检索一行或一部分行。
  • 支持对结果集中当前位置的行进行数据修改。
  • 为由其他用户对显示在结果集中的数据库数据所做的更改提供不同级别的可见性支持。
  • 提供脚本、存储过程和触发器中用于访问结果集中的数据的 Transact-SQL 语句。

——MSDN

不难理解,游标与其他数据库操作的最大不同就是对象是单条记录而不是结果集,一般用于过程化程序里嵌入的SQL语句。在数据库服务程序里用到了自动隐含创建的游标。

2    基本用法:

2.1 声明游标

DECLARE 游标名 CURSOR

FOR SELECT语句

2.2 打开游标

OPEN 游标名

2.3 从游标获取数据

FETCH NEXT FROM 游标名 [ INTO FETCH_LIST ]

从游标获取数据需要注意可能到达游标末尾,以下方法解决这个问题以避免用户在关闭游标时产生错误

 BEGIN
DECLARE @custname VARCHAR(20)
DECLARE namecursor CURSOR FOR SELECT CUST_NAME FROM TBL_CUSTOMER OPEN namecursor
FETCH NEXT FROM namecursor INTO @custname
WHILE (@@FETCH_STATUS <> -1)
BEGIN
IF (@@FETCH_STATUS <> -2)
BEGIN
--操作游标变量
END
FETCH NEXT FROM namecursor INTO @custname
END
CLOSE namecursor
DEALLOCATE namecursor
END

2.4 关闭游标

CLOSE 游标名

关闭后不能对游标进行读取等操作,但可以使用OPEN语句再次打开

2.5 释放游标

DEALLOCATE 游标名

即删除游标,不可再使用

3    一个有意思的小例子:

虽然知道了游标的概念和基本用法,但对于什么时候用游标还很模糊,甚至误认为游标可以被子查询所代替。直到遇到了这个有意思的小例子:

表结构如下:

题目要求是:列出从事同一种工作但属于不同部门的雇员的不同组合

即如下结果:

在想尽了子查询、表连接、建临时表等等办法之后,我发现我遇到了一个不可逾越的障碍:无法排除两个名字组合的唯一性。即:我得到的结果可能是如下

ANAME BNAME
Adams James
James Adams

最终我想到了刚学到的游标,代码如下

 SELECT A.Ename AS ANAME, B.Ename AS BNAME
INTO #t
FROM EMP A
JOIN EMP B
ON A.job = B.job AND A.deptNo <> B.deptNo and A.Ename<>b.Ename
ORDER BY ANAME --DROP TABLE #t DECLARE TEST_CURSOR CURSOR FOR
SELECT ANAME, BNAME FROM #t OPEN TEST_CURSOR
DECLARE @ANAME VARCHAR(20)
DECLARE @BNAME VARCHAR(20) FETCH NEXT FROM TEST_CURSOR INTO @ANAME, @BNAME
DELETE FROM #t WHERE ANAME=@BNAME AND BNAME=@ANAME
WHILE @@FETCH_STATUS = 0
BEGIN
FETCH NEXT FROM TEST_CURSOR INTO @ANAME, @BNAME
DELETE FROM #t WHERE ANAME=@BNAME AND BNAME=@ANAME
END CLOSE TEST_CURSOR
DEALLOCATE TEST_CURSOR SELECT * FROM #t

--------------------------------------------------------------------------------------

--12.2更新:

突然发现这题可以用极其简单的方法写出来,用游标简直Stupid~~

 SELECT A.Ename AS ANAME, B.Ename AS BNAME
FROM EMP A, EMP B
WHERE A.job = B.job AND A.deptNo <> B.deptNo AND A.Ename < B.Ename
ORDER BY ANAME

掩面遁走~~

从一个小例子认识SQL游标的更多相关文章

  1. java连接mysql的一个小例子

    想要用java 连接数据库,需要在classpath中加上jdbc的jar包路径 在eclipse中,Project的properties里面的java build path里面添加引用 连接成功的一 ...

  2. java操作xml的一个小例子

    最近两天公司事比较多,这两天自己主要跟xml打交道,今天更一下用java操作xml的一个小例子. 原来自己操作xml一直用这个包:xstream-1.4.2.jar.然后用注解的方式,很方便,自己只要 ...

  3. MVVM模式的一个小例子

    使用SilverLight.WPF也有很长时间了,但是知道Binding.Command的基本用法,对于原理性的东西,一直没有深究.如果让我自己建一个MVVM模式的项目,感觉还是无从下手,最近写了一个 ...

  4. 使用Trinity拼接以及分析差异表达一个小例子

    使用Trinity拼接以及分析差异表达一个小例子  2017-06-12 09:42:47     293     0     0 Trinity 将测序数据分为许多独立的de Brujin grap ...

  5. 关于SVN配置文件的一个小例子

    1   背景假设 厦门央瞬公司是一家电子元器件设备供应商,其中有个ARM部门,专门负责ARM芯片的方案设计.销售,并在北京.上海各设立了一个办事处.对于工作日志,原先采用邮件方式发给经理,但是这种方式 ...

  6. Vue2.x源码学习笔记-从一个小例子查看vm实例生命周期

    学习任何一门框架,都不可能一股脑儿的从入口代码从上到下,把代码看完, 这样其实是很枯燥的,我想也很少有人这么干,或者这么干着干着可能干不下去了. 因为肯定很无聊. 我们先从一个最最简单的小例子,来查看 ...

  7. Hibernate入门1 - Hibernate概述及第一个小例子

    一.什么是ORM? ORM,即Object Relational Mapping.我们知道,利用面向对象的思想编写的数据库应用程序最终都是把对象信息保存在关系型数据库中,于是需要编写与底层数据库相关的 ...

  8. Spring和Hibernate结合的一个小例子

    1.新建一个SpringHibernate的maven项目 2.pom文件的依赖为 <dependency> <groupId>junit</groupId> &l ...

  9. Spring.Net在ASP.NET Mvc里使用的一个小例子

    就贴个小例子,就不注意格式了. 1.下载dll NuGet的下载地址:http://docs.nuget.org/docs/start-here/installing-nuget 在vs的NuGet里 ...

随机推荐

  1. 关于iOS多线程,你看我就够了

    在这篇文章中,我将为你整理一下 iOS 开发中几种多线程方案,以及其使用方法和注意事项.当然也会给出几种多线程的案例,在实际使用中感受它们的区别.还有一点需要说明的是,这篇文章将会使 用 Swift  ...

  2. Android系统Surface机制的SurfaceFlinger服务的启动过程分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8022957 在前面一篇文章中,我们简要介绍了A ...

  3. MFC多线程内存泄漏问题&amp;解决方法

    在用visual studio进行界面编程时(如MFC),前台UI我们能够通过MFC的消息循环机制实现.而对于后台的数据处理.我们可能会用到多线程来处理. 那么对于大多数人(尤其是我这样的菜鸟),一个 ...

  4. linux光盘、U盘的挂载与卸载

    mount [-t vfstype] [-o options] device dir1.-t vfstype 指定文件系统的类型,通常不必指定.mount 会自动选择正确的类型.关于一些常用的文件:i ...

  5. js 行列操作

    function insertRow() { var tbl = document.getElementById("tbCarModel"); var rowLen = tbl.c ...

  6. 使用SQLCipher加密数据库

      Xcode中集成了免费的sqlite,但是不提供加密的模块,突然有一天,蛋疼的客户要求把数据进行加密,于是乎就寻找使用简单并且可以把数据迁移过度到加密数据库的框架. SQLCipher是第三方的开 ...

  7. 【IOS学习基础】归档和解档

    一.归档介绍 1.归档是指用某种格式来保存一个或多个对象,以便以后还原这些对象的过程.归档是将数据持久化的一种方式(所谓数据持久化,就是指在IOS开发过程中,将数据保存到本地,能够让程序的运行更加流畅 ...

  8. bootstrap 之 列表组件使用

    列表是几乎所有网站都会用到的一个组件,正好bootstrap也给我们提供了这个组件的样式,下面我给大家简单介绍一下bootstrap中的列表组件的用法! 首先,重提一下引用bootstrap的核心文件 ...

  9. 安装TDM-GCC

    TDM-GCC是一组免费的编译器套件,有32位和64位两种版本.其中64位版既可以编译生成64位的可执行文件,又可以编译生成32位的可执行文件.从TDM-GCC的官网可以下载到相应的安装包,安装完成后 ...

  10. kettle新建资源库出错

    之前在本地测试新建kettle资源库很顺利,但是在把本地数据迁移到服务器的过程中出现了问题,多次新建资源库失败,提示插入数据错误. 解决办法: 将要执行的sql语句复制出来,单独在Navicat下执行 ...