MSSQL之游标的用法

本文详细介绍了 SQL Server 中游标的使用方法,包括 Transact-SQL、OLEDB、ODBC 和 C 语言等不同环境下的实现方式,并通过创建银行信息表展示如何利用游标逐行处理结果集。同时,演示了通过游标筛选 VIP 客户的综合应用实例。
再来看看MSSQL中的游标。
我们知道所有SQL语句都在行集上运行。SELECT语句返回包含所有满足SELECT语句限定条件的行的完整结果集。应用程序需要一次处理结果集的一行或一个行块。游标是结果集的逻辑扩展,它使应用程序得以逐行处理结果集。
SQL SERVER支持多种指定游标的机制: 
1、Transact-SQL支持用于管理游标的SQL-92 DECLARE CURSOR、OPEN、FETCH 和CLOSE语句。Transact-SQL还支持游标扩展,如: 
  (1)、允许对重新使用游标进行优化的DEALLOCATE语句。//删除游标
  (2)、定义Transact-SQL变量以具有游标数据类型,然后用它引用游标。
  (3)、定义具有局部或全局作用域的游标。
  (4)、在DECLARE CURSOR 语句内指定符合OLE DB和ODBC规范的游标类型(FORWARD_ONLY、STATIC、KEYSET和  DYNAMIC)。 
2、用于SQL Server的Microsoft OLE DB 提供程序支持ADO和OLE DB API的游标功能。
3、Microsoft SQL Server ODBC驱动程序支持ODBC、RDO、DAO和Microsoft基础类数据库类API的游标功能。
4、用于C语言的Microsoft嵌入式SQL支持嵌入式SQL标准的游标功能。
5、DB-Library API支持与OLE DB和ODBC API相同级别的游标功能。 

首先,我们创建一个银行信息表
IF OBJECT_ID('bankInfo') IS NOT NULL 
DROP TABLE bankInfo
GO
--银行卡信息表
CREATE TABLE bankInfo
(
   uId VARCHAR(18) NOT NULL PRIMARY KEY,--卡号
   uName VARCHAR(20), --卡主姓名
   uMoney MONEY       --卡中余额
)
GO
INSERT INTO bankInfo VALUES('9559901','张三',1)
INSERT INTO bankInfo VALUES('9559902','李四',1000)
INSERT INTO bankInfo VALUES('9559903','王五',800)
INSERT INTO bankInfo VALUES('9559904','赵六',50)
INSERT INTO bankInfo VALUES('9559905','赵明',5)

SELECT * FROM bankInfo,结果显示如下:
/*
uId                uName                uMoney
------------------ -------------------- ---------------------
9559901            张三                   1.00
9559902            李四                   1000.00
9559903            王五                   800.00
9559904            赵六                   50.00
9559905            赵明                   5.00

(5 行受影响)
*/
创建了游标之后,必须要打开才能使用,还是用T-SQL举个示例来说明一下游标的使用
-----------游标的使用----------------
DEALLOCATE CursorBank  --删除游标
GO
--------定义游标-----------------
DECLARE CursorBank CURSOR SCROLL  
FOR SELECT * FROM bankInfo
GO
OPEN CursorBank --从游标读取数据前必须先打开游标
FETCH FIRST FROM CursorBank  --读取第一行
/*
uId                uName                uMoney
------------------ -------------------- ---------------------
9559901            张三                   401.00

(1 行受影响)
*/

FETCH NEXT FROM CursorBank   --上次读取行的下一行
/*
uId                uName                uMoney
------------------ -------------------- ---------------------
9559902            李四                   600.00

(1 行受影响)
*/

FETCH PRIOR FROM CursorBank  --上次读取行的上一行
/*
uId                uName                uMoney
------------------ -------------------- ---------------------
9559901            张三                   401.00

(1 行受影响)
*/

FETCH LAST FROM CursorBank   --最后一行
/*
uId                uName                uMoney
------------------ -------------------- ---------------------
9559905            赵明                   5.00

(1 行受影响)
*/

FETCH ABSOLUTE 2 FROM CursorBank --定位到第三行
/*
uId                uName                uMoney
------------------ -------------------- ---------------------
9559902            李四                   600.00

(1 行受影响)
*/

FETCH RELATIVE -1 FROM CursorBank --相对位置定位,根据当前游标位置
/*
uId                uName                uMoney
------------------ -------------------- ---------------------
9559901            张三                   401.00

(1 行受影响)
*/
来看一个综合点的游标应用
--通过游标读取数据,如果余额大于等于500,
--则显示该储户为贵宾客户
--全局变量@@FETCH_STATUS表示上一个FETCH是否读取
--到了数据,其返回值类型为int型
--  值有三种:
--   0 : FETCH语句成功
--  -1 : FETCH语句失败或此行不在结果集中
--  -2 : 被提取行不存在
sql语句如下:

DECLARE @id VARCHAR(12),@name VARCHAR(20)
DECLARE @getMoney MONEY
FETCH FIRST FROM CursorBank INTO @id,@name,@getMoney
WHILE @@FETCH_STATUS=0 --上一个fetch是否读取到了数据
    BEGIN 
      IF(@getMoney>500)
        PRINT '你是VIP用户'+',账号:'+@id+',姓名:'+@name+',账户余额:'+CONVERT(VARCHAR(12),@getMoney)
      ELSE
        PRINT @name+',您不是VIP用户!'    
      FETCH NEXT FROM CursorBank INTO @id,@name,@getMoney
    END
运行结果如下:
/*
张三,您不是VIP用户!
你是VIP用户,账号:9559902,姓名:李四,账户余额:600.00
你是VIP用户,账号:9559903,姓名:王五,账户余额:800.00
赵六,您不是VIP用户!
赵明,您不是VIP用户!
*/
   以上是关于MSSQL中游标的简单示例,我只是简单总结一下,新手可以看看,SQL高手就没必要了。写的不对的地方欢迎批评指正。关于游标的高级用法还是得在项目中慢慢积累和学习。


在 MySQL 中,游标(Cursor)是一种用于在存储过程或函数中逐行处理查询结果集的机制。MySQL游标属于**静态游标**的一种实现,其特性与传统数据库系统中的静态游标相似,即在游标打开时生成一个临时的结果集副本[^1]。 ### 游标的声明与使用流程 1. **声明游标** 使用 `DECLARE` 语句定义一个游标,并绑定到一个 `SELECT` 查询上。该查询决定了游标所遍历的数据集。 ```sql DECLARE m_soult CURSOR FOR SELECT `id`, `orderno`, COUNT(*) t FROM hb_shipper_order GROUP BY orderno HAVING t > 1; ``` 上述示例声明了一个名为 `m_soult` 的游标,用于遍历具有重复 `orderno` 的记录[^2]。 2. **声明变量用于接收数据** 在游标遍历时,需要声明变量来接收每一行的数据: ```sql DECLARE v_id INT; DECLARE v_orderno VARCHAR(255); DECLARE v_count INT; ``` 3. **声明条件处理程序(可选)** 当游标遍历到结果集末尾时,通常会触发 `NOT FOUND` 条件。可以使用 `DECLARE CONTINUE HANDLER` 对其进行处理: ```sql DECLARE CONTINUE HANDLER FOR NOT FOUND SET no_more_record = 1; ``` 其中 `no_more_record` 是一个用户定义的变量,用于控制循环结束[^3]。 4. **打开游标** 使用 `OPEN` 语句打开游标,此时会执行绑定的 `SELECT` 查询并将结果集存入临时表: ```sql OPEN m_soult; ``` 5. **获取游标数据** 使用 `FETCH` 语句将当前行的数据赋值给变量: ```sql FETCH m_soult INTO v_id, v_orderno, v_count; ``` 6. **关闭游标** 使用 `CLOSE` 语句释放游标资源: ```sql CLOSE m_soult; ``` ### 完整示例:使用游标遍历数据 以下是一个完整的存储过程示例,展示了如何使用游标遍历重复订单号的记录: ```sql DELIMITER $$ CREATE PROCEDURE ProcessDuplicateOrders() BEGIN DECLARE v_id INT; DECLARE v_orderno VARCHAR(255); DECLARE v_count INT; DECLARE no_more_record INT DEFAULT 0; -- 声明游标 DECLARE m_soult CURSOR FOR SELECT `id`, `orderno`, COUNT(*) t FROM hb_shipper_order GROUP BY orderno HAVING t > 1; -- 声明 NOT FOUND 处理器 DECLARE CONTINUE HANDLER FOR NOT FOUND SET no_more_record = 1; -- 打开游标 OPEN m_soult; -- 开始遍历 read_loop: LOOP FETCH m_soult INTO v_id, v_orderno, v_count; -- 判断是否结束 IF no_more_record THEN LEAVE read_loop; END IF; -- 输出或处理数据 SELECT v_orderno, v_count; END LOOP; -- 关闭游标 CLOSE m_soult; END$$ DELIMITER ; ``` ### 注意事项 - MySQL 游标仅支持在存储过程、函数或触发器中使用,不能在普通的 SQL 查询中直接使用。 - 游标是只读的,且默认为静态游标,不会反映其他会话对底层表的更改[^1]。 - 避免在大数据量下频繁使用游标,因其性能较低,建议优先考虑集合操作。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值