一文详解数据库“游标”

一、什么是“游标(Cursor)”?

游标是SQL 的一种数据访问机制 ,游标是一种处理数据的方法。众所周知,使用SQL的select查询操作返回的结果是一个包含一行或者是多行的数据集,如果我们要对查询的结果再进行查询,比如(查看结果的第一行、下一行、最后一行、前十行等等操作)简单的通过select语句是无法完成的,因为这时候索要查询的结果不是数据表,而是已经查询出来的结果集。游标就是针对这种情况而出现的。

我们可以将“ 游标 ”简单的看成是结果集的一个指针,可以根据需要在结果集上面来回滚动,浏览我需要的数据。

二、游标的操作——五步走

声明游标—>打开游标—>读取数据—>关闭游标—>删除游标

1、声明游标——Declare cursorname Cursor

语法如下:

declare cursor_name Corsor [ LOCAL | GLOBAL]  [ FORWARD_ONLY | SCROLL ] [ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ] [ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ] [ TYPE_WARNING ]

for

Slect查询的相关语句

上面的彩色字体表示的是,声明游标时的选项,不是必须提供的,每一个都代表游标的相关选项和特性

(1)LOCAL对于在其中创建批处理、存储过程或触发器来说,该游标的作用域是局部的。GLOBAL指定该游标的作用域是全局的

(2)FORWARD_ONLY:指定游标只能从第一行滚动到最后一行。否则默认为FORWARD_ONLY。SCROLL表示游标可以来回滚动

(3)STATIC定义一个游标,以创建将又该游标使用的数据临时复本,对游标的所有请求都从tempdb中的这以临时表中不得到应答;因此,在对该游标进行提取操作时返回的数据中不反映对基表所做的修改,并且该游标不允许修改。

  KEYSET:指定当游标打开时,游标重的行的成员身份和顺序已经固定。对行进行唯一标识的键值内置在tempdb内一个称为keyset的表中。

     DYNAMIC:定义一个游标,以反映在滚动游标时对结果集内的各行所做的所有数据更改。行的数据值、顺序和成员身份在每次提取时都会更改,动态游标不支持ABSOLUTE提取选项。

     FAST_FORWARD指定启动了性能优化的FORWARD_ONLY、READ_ONLY游标。如果指定了SCROLL或FOR_UPDATE,则不能指定FAST_FORWARD。

      SCROLL_LOCKS指定通过游标进行的定位更新或删除一定会成功。将行读入游标时SQL Server将锁定这些行,以确保随后可对它们进行修改,如果还指定了FAST_FORWARD或STATIC,则不能指定SCROLL_LOCKS。

   OPTIMISTIC指定如果行自读入游标以来已得到更新,则通过游标进行的定位更新或定位删除不成功。当将行读入游标时,SQL Server不锁定行,它改用timestamp列值比较结果来确定行读入游标后是否发生了修改,如果表不包含timestamp列,它改用校验和值进行确定,如果以修改该行,则尝试进行的定位更新或删除将失败,如果还指定了FAST_FORWARD,则不能指定OPTIMISTIC。

  TYPE_WARNING:指定游标从所请求的类型隐式转换为另一种类型时,向客户端发送警告消息。

2、打开游标——Open Cursorname

3、取出数据——Fetch.........From

Fetch   [ NEXT | PRIOR | FIRST | LAST  | ABSOLUTE { n | @nvar }  | RELATIVE { n | @nvar }]     FROM Cursorname            

[ INTO @variable_name [ ,...n ] ]

NEXT:紧跟当前行返回结果行,并且当前行递增为返回行,如果FETCH NEXT为对游标的第一次提取操作,则返回结果集中的第一行。NEXT为默认的游标提取选项。

PRIOR返回紧邻当前行前面的结果行,并且当前行递减为返回行,如果FETCH PRIOR为对游标的第一次提取操作,则没有行返回并且游标置于第一行之前。

FIRST返回游标中的第一行并将其作为当前行。

LAST:返回游标中的最后一行并将其作为当前行。

ABSOLUTE { n | @nvar }如果n或@nvar为正,则返回从游标头开始向后n行的第n行,并将返回行变成新的当前行。如果n或@nvar为负,则返回从游标末尾开始向前的n行的第n行,并将返回行变成新的当前行。如果n或@nvar为0,则不返回行。n必须是整数常量,并且@nvar的数据类型必须为int、tinyint或smallint.

RELATIVE { n | @nvar }如果n或@nvar为正,则返回从当前行开始向后的第n行。如果n或@nvar为负,则返回从当前行开始向前的第n行。如果n或@nvar为0,则返回当前行,对游标第一次提取时,如果在将n或@nvar设置为负数或0的情况下指定FETCH RELATIVE,则不返回行,n必须是整数常量,@nvar的数据类型必须是int、tinyint或smallint.

GLOBAL指定cursor_name是全局游标。

cursor_name已声明的游标的名称。如果全局游标和局部游标都使用cursor_name作为其名称,那么如果指定了GLOBAL,则cursor_name指的是全局游标,否则cursor_name指的是局部游标。

@cursor_variable_name游标变量名,引用要从中进行提取操作的打开的游标。

INTO @variable_name [ ,...n ]允许将提取操作的列数据放到局部变量中。列表中的各个变量从左到右与游标结果集中的相应列相关联。各变量的数据类型必须与相应的结果集列的数据类型相匹配,或是结果集列数据类型所支持的隐士转换。变量的数目必须与游标选择列表中的列数一致。

4、关闭游标——Close Cursorname

5、删除游标——Deallocate Cursorname

三、操作案例

因为Access不支持游标、MySQL要5.0版本之后才支持,SQLite支持的游标称之为“步骤(Step)”,故而,本文以SQL Server为例加以说明。

declare productcursor cursor scroll      --第一步:声明游标
for 
select * from productinfo where vendname='上海华测'
GO
open productcursor                       --第二步:打开游标
Go
--读取数据开始                            --第三步:获取数据
fetch next from productcursor --读取当前行的下一行,并使其置为当前行(刚开始时游标置于表头的前一行,即若表是从0开始的,游标最初置于-1处,所以第一次读取的是头一行)
fetch prior from productcursor --读取当前行的前一行,并使其置为当前行
fetch first from productcursor --读取游标的第一行,并使其置为当前行(不能用于只进游标)
fetch last from productcursor  --读取游标的最后一行,并使其置为当前行(不能用于只进游标)
fetch absolute 2 from productcursor --读取从游标头开始向后的第2行,并将读取的行作为新的行
fetch relative 3 from productcursor --读取从当前行开始向后的第3行,并将读取的行作为新的行
fetch relative-2 from productcursor --读取当前行的上两行,并将读取的行作为新的行
--读取数据结束
GO
close productcursor                      --第四步:关闭游标
Go
deallocate productcursor                 --第五步:删除游标
Go

 

Oracle数据库游标是一种用于处理查询结果集数据库对象。它允许开发人员在PL/SQL代码中对查询结果进行迭代和操作。以下是Oracle数据库游标的使用方法: 1. 声明游标:使用`DECLARE`语句声明游标,并指定游标的名称和返回的结果集。 2. 打开游标:使用`OPEN`语句打开游标,将查询结果集绑定到游标上。 3. 获取数据:使用`FETCH`语句从游标中获取一行或多行数据,并将其存储在变量中供后续处理。 4. 处理数据:对获取的数据进行处理,可以使用条件语句、循环语句等进行逻辑操作。 5. 关闭游标:使用`CLOSE`语句关闭游标,释放资源并结束游标的使用。 下面是一个示例代码,演示了如何使用游标来获取查询结果集中的数据: ``` DECLARE CURSOR c_emp IS SELECT employee_id, first_name, last_name FROM employees; v_emp_id employees.employee_id%TYPE; v_first_name employees.first_name%TYPE; v_last_name employees.last_name%TYPE; BEGIN OPEN c_emp; LOOP FETCH c_emp INTO v_emp_id, v_first_name, v_last_name; EXIT WHEN c_emp%NOTFOUND; -- 处理数据,例如打印员工信息 DBMS_OUTPUT.PUT_LINE('Employee ID: ' || v_emp_id); DBMS_OUTPUT.PUT_LINE('First Name: ' || v_first_name); DBMS_OUTPUT.PUT_LINE('Last Name: ' || v_last_name); END LOOP; CLOSE c_emp; END; ``` 在上述示例中,我们声明了一个名为`c_emp`的游标,然后使用`OPEN`语句打开游标。在循环中,使用`FETCH`语句从游标中获取一行数据,并将其存储在相应的变量中。然后可以对获取的数据进行处理,例如打印员工信息。最后使用`CLOSE`语句关闭游标
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值