Sql server中的Cursor

本文介绍了如何在SQL Server中使用游标逐条访问数据,并通过示例展示了游标的使用方法。此外,文章还讨论了游标对数据库性能的影响,并介绍了隐式游标的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有时候我们需要逐条地读取数据,就像下面这样:

this.sqlConnection1.Open();
SqlDataReader myReader 
= this.sqlCommand1.ExecuteReader();
do
{
while (myReader.Read())
      {
Console.WriteLine(" {
0} {1}", myReader.GetInt32(0), myReader.GetString(1));
while (myReader.NextResult());
myReader.
Close();
      sqlConnection1.
Close();    

我们经常会这样在自己的程序中这样去写,但是怎么在SQL Server 中逐条访问数据,当然是有办法的,那就是游标。
比方说:
我想从Nurthwind数据库的Employees中查找TitleOfCourtesy为‘Mr.'的所有人的LastName和FirstName,同时我需要逐条访问,下面是示例:

USE Northwind
GO
--定义游标
DECLARE myCursor CURSOR FOR
SELECT LastName, FirstName FROM Employees
WHERE TitleOfCourtesy ='Mr.'
--打开游标
OPEN myCursor
--逐行读取
FETCH NEXT FROM myCursor
--@@FETCH_STATUS,FETCH 语句成功
WHILE @@FETCH_STATUS = 0
BEGIN  
   
FETCH NEXT FROM myCursor
END
--关闭游标
CLOSE myCursor
--释放游标
DEALLOCATE myCursor
GO

就这样逐条的结果读出来了

但 是游标占用内存,还用它们那些不可思议的方式锁定表。每执行一次FETCH就等于执行一次SELECT命令?这意味着如果你的游标有10000条记录,它 将执行10000次SELECT!如果你使用一组SELECT、UPDATE或者DELETE来完成相应的工作,那将有效率的多。
关于游标与数据库性能:
Cursor threshold选项
用于指定游标集的行数。
如果设置为-1,则所有的游标集将同步产生,对于小游标集会非常有用
如果设置为0,则所有的游标集将异步产生,这对于数量很大的游标集会有帮助
如果设置为其它值,异步和同步将由游标集中所期望的行数和游标阈值的设置值比较决定。前者大于后者,异步;否则,同步。
可以使用sp_configure系统存储过程来修改该设置。当注意的是只有show advanced options为1时才可更改。同时该设置修改后立即生效,无须重启数据库。

 
2.2 隐式游标



       所有的隐式游标都被假设为只返回一条记录。

       使用隐式游标时,用户无需进行声明、打开及关闭。PL/SQL隐含地打开、处理,然后关掉游标。

       例如:

       …….

       SELECT studentNo,studentName

       INTO curStudentNo,curStudentName

       FROM StudentRecord

       WHERE name=’gg’;

       上述游标自动打开,并把相关值赋给对应变量,然后关闭。执行完后,PL/SQL变量curStudentNo,curStudentName中已经有了值。

游标四大隐式属性

%found、%notfound、%isopen、%rowcount

其中%found、%notfound、%isopen的结果为boolean型,%rowcount结果为整数。

举例说明:
test表数据
 A NAME
-- -----
 1 aa
 2 bb
 3 cc
 4 dd
 5 ee

程序:
set serveroutput on
declare
cursor abc(idpara number) is   --带参数
select name from test where a=idpara;
t_name test.name%type;
e exception;     --自定义异常
nopen exception;    --自定义异常
begin
open abc('3');     --参数idpara赋值为3
fetch abc into t_name;
if abc%isopen then    --如果游标已打开
dbms_output.put_line('cursor is open');
else
raise nopen;     --抛出自定义异常(游标未打开)
end if;
if abc%notfound then    --如果数据没有找到
raise e;     --抛出自定义异常(数据没有找到)
elsif abc%found then    --如果数据找到
dbms_output.put_line(t_name);
dbms_output.put_line('I found '||abc%rowcount||' data!'); --输出找到多少个数据
end if;
exception    
when nopen then       --游标未打开异常执行
dbms_output.put_line('The cursor is not found!');  
when e then       --数据未找到异常执行
dbms_output.put_line('The eid is not found!');
end;
/

完成。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值