游标概念
SQL是面向集合的,一条SQL语句可以处理多条记录;
主语言是面向记录的,主变量一次只能放进一条记录。
为了协调这两种不同处理方式,引入游标。相当于一个数据缓冲区。
通过游标逐一获取一条记录,并赋给主变量,交由主语言进一步处理。
游标的使用
有些像文件的使用,需要定义声明,打开关闭,操作等等。
前面都要加EXEC SQL,表示执行SQL语句。
(1)说明游标(声明——DECLARE)
EXEC SQL DECLARE <游标名> CURSOR FOR <SELECT语句>;
只是说明,并没有执行其中的SELECT语
(2)打开游标——OPEN
EXEC SQL OPEN <游标名>;
打开就是执行其中的SELECT语句,把查询结果取到缓冲区,这时游标指针指向第一条记录。
(3)推进游标指针并取当前记录——FETCH…INTO
EXEC SQL FETCH <游标名>
INTO <主变量>[<指示变量>][,<主变量>[<指示变量>]]...;
FETCH向前推进一步游标,将当前记录取出给主变量。FETCH只向前推进一步。需要用循环执行得到其所有结果。
(4)关闭游标——CLOSE
EXEC SQL CLOSE <游标名>;
也可以用游标更新或删除某个记录。用CURRENT形式的UPDATE和DELETE语句。前提是要用带游标的SELECT语句查出所有满足条件的记录后,在进一步找到要更新的记录,然后使用如下语句:
WHERE CURRENT OF <游标名>;
这个语句表示游标指向的当前记录。
注:SELECT语句中带有UNION或ORDER BY 语句的时候,相当于定义了一个不可更新的视图,不能使用。
游标使用例子
例(课本上的【例8.1】部分):
标准SQL:
EXEC SQL DECLARE SX CURSOR FOR
SELECT Sno,Sname,Ssex,Sage
FROM Student
WHERE Sdept = :deptname;--:deptname是前面声明的主变量
--说明游标
EXEC SQL OPEN SX; --打开游标
for(;;)
{EXEC SQL FETCH SX INTO :HSno,:HSname,:HSsex,:HSage;...}
--循环,推进游标
...
EXEC SQL UPDATE Student
SET Sage = :NEWAGE
WHERE CURRENT OF SX;
--对游标当前指向的记录的Sage进行更新
EXEC SQL CLOSE SX; --关闭游标
T-SQL:
IF (exists (select * from sys.objects where name = 'proc_cursor'))
DROP PROCEDURE proc_cursor
GO
CREATE PROCEDURE proc_cursor -- 存储过程
AS
DECLARE @Sno char(9)--定义变量
DECLARE @Sname char(20)--定义变量
DECLARE mycursor CURSOR FOR select Sno,Sname from Student --声明游标
OPEN mycursor --打开游标
FETCH NEXT FROM mycursor INTO @Sno,@Sname
WHILE(@@FETCH_STATUS=0) --遍历所有的数据
BEGIN
PRINT '游标成功取出一条数据:'
PRINT @Sno
PRINT @Sname
PRINT '********************'
FETCH NEXT FROM mycursor INTO @Sno,@Sname --取下一条游标数据
END
CLOSE mycursor --关闭游标
DEALLOCATE mycursor --删除游标
GO
EXEC proc_cursor
GO
这里创建了存储过程
运行结果:
这个结果与SELECT语句单独执行的结果是一致的。
【心得】游标做起来还是比较简单的,可能是这些例子只是在用游标,嵌套到主语言中,在循环里面,推进游标后面加相关操作即可。