从一个小例子认识SQL游标

简介: 原文:从一个小例子认识SQL游标1    什么是游标: 关系数据库中的操作会对整个行集起作用。 例如,由 SELECT 语句返回的行集包括满足该语句的 WHERE 子句中条件的所有行。 这种由语句返回的完整行集称为结果集。
原文: 从一个小例子认识SQL游标

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 ]

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

 1 BEGIN
 2   DECLARE @custname VARCHAR(20)
 3   DECLARE namecursor CURSOR FOR SELECT CUST_NAME FROM TBL_CUSTOMER OPEN namecursor
 4   FETCH NEXT FROM namecursor INTO @custname
 5   WHILE (@@FETCH_STATUS <> -1)
 6   BEGIN
 7     IF (@@FETCH_STATUS <> -2)
 8       BEGIN
 9         --操作游标变量
10       END
11     FETCH NEXT FROM namecursor INTO @custname
12   END
13   CLOSE namecursor
14   DEALLOCATE namecursor
15 END

2.4 关闭游标

CLOSE 游标名

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

2.5 释放游标

DEALLOCATE 游标名

即删除游标,不可再使用

 

3    一个有意思的小例子:

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

表结构如下:

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

即如下结果:

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

ANAME BNAME
Adams James
James Adams

 

 

 

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

 1 SELECT A.Ename AS ANAME, B.Ename AS BNAME
 2 INTO #t
 3 FROM EMP A
 4 JOIN EMP B 
 5 ON A.job = B.job AND A.deptNo <> B.deptNo and A.Ename<>b.Ename
 6 ORDER BY ANAME
 7 
 8 DECLARE TEST_CURSOR CURSOR FOR
 9 SELECT ANAME, BNAME FROM #t
10 
11 OPEN TEST_CURSOR
12 DECLARE @ANAME VARCHAR(20)
13 DECLARE @BNAME VARCHAR(20)
14 
15 FETCH NEXT FROM TEST_CURSOR INTO @ANAME, @BNAME
16 DELETE FROM #t WHERE ANAME=@BNAME AND BNAME=@ANAME
17 WHILE @@FETCH_STATUS = 0
18 BEGIN 
19 FETCH NEXT FROM TEST_CURSOR INTO @ANAME, @BNAME
20 DELETE FROM #t WHERE ANAME=@BNAME AND BNAME=@ANAME
21 END
22 
23 CLOSE TEST_CURSOR
24 DEALLOCATE TEST_CURSOR
25 
26 SELECT * FROM #t

最终得到了预期结果,但我想这个问题可能不止这一种解法,希望有其他解法的大牛能指点一二 ^^

目录
相关文章
|
5天前
|
SQL Oracle 关系型数据库
Oracle的PL/SQL游标属性:数据的“导航仪”与“仪表盘”
【4月更文挑战第19天】Oracle PL/SQL游标属性如同车辆的导航仪和仪表盘,提供丰富信息和控制。 `%FOUND`和`%NOTFOUND`指示数据读取状态,`%ROWCOUNT`记录处理行数,`%ISOPEN`显示游标状态。还有`%BULK_ROWCOUNT`和`%BULK_EXCEPTIONS`增强处理灵活性。通过实例展示了如何在数据处理中利用这些属性监控和控制流程,提高效率和准确性。掌握游标属性是提升数据处理能力的关键。
|
3月前
|
SQL 存储 Perl
PL/SQL的游标
PL/SQL的游标
26 2
|
4月前
|
存储 SQL Oracle
|
5月前
|
SQL
sql游标的使用
sql游标的使用
21 0
|
8月前
|
SQL
sql server 游标的使用
sql server 游标的使用
40 0
|
9月前
|
SQL 存储 数据库
SQL Server—游标(是什么?声明、打开、检索、关闭、释放)
是一种数据访问机制,它允许用户单独的操作数据行,而不是对整个行集进行操作。用户可以通过单独处理每一行逐条手机信息并对数据逐行进行操作,这样可以降低系统开销和潜在的阻隔情况。用户也可以使用这些数据生成SQL代码并立即执行或输出
|
10月前
|
SQL 缓存 监控
为什么Oracle中包含绑定变量的SQL会有多个游标?(译文)
为了改进包含绑定变量的SQL的执行计划,Oracle在11g版本中引入了一项名为自适应游标共享(ACS,Adaptive Cursor Sharing)的新功能。
106 0
|
11月前
|
SQL 存储 Oracle
PL/SQL编程—游标
PL/SQL编程—游标
76 0
|
存储 SQL 安全
SQL 存储过程和函数的对比、变量、条件和处理程序、游标、流程控制详解+代码示例
SQL 存储过程和函数的对比、变量、条件和处理程序、游标、流程控制详解+代码示例
|
存储 SQL 程序员
【Sql Server】 使用游标循环记录更新字段值
使用游标循环记录更新字段值
326 0
【Sql Server】 使用游标循环记录更新字段值