关于mysql游标

154 阅读7分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第20天,点击查看活动详情

游标的概念

游标提供了一种从表中检索数据并进行操作的灵活手段,游标主要用在服务器上,处理由客户端发送给服务器端的SQL语句,或是批处理存储过程、触发器中的数据处理请求。

游标的优点在于它可以定位到结果集中的某一行,并可以对该行数据执行特定操作,为用户在处理数据的过程中提供了很大方便。

游标的顺序:

1. 声明游标

声明游标使用DECLARE CURSOR语句。此语句有两种语法声明格式,分别为SQL 92标准格式和SQL Server扩展(扩展了声明游标的参数)格式,下面将分别介绍声明游标的两种语法格式。

1)sql——92

DECLARE cursor_name [ INSENSITIVE ] [ SCROLL ] CURSOR

FOR select_statement

FOR { READ ONLY | UPDATE [ OF column_name [ ,...n ] ] } ]

参数说明:

cursor_name:指定一个游标名称,其游标名称必须符合标识符规则。

INSENSITIVE:定义一个游标,以创建将由该游标使用的数据的临时复本。对游标的所有请求都从tempdb中的临时表中得到应答;因此,在对该游标进行提取操作时返回的数据中不反映对基表所做的修改,并且该游标不允许修改。使用SQL-92语法时,如果省略INSENSITIVE,(任何用户)对基表提交的删除和更新都反映在后面的提取中。

SCROLL:指定所有的提取选项(FIRST、LAST、PRIOR、NEXT、RELATIVE、ABSOLUTE)均可用。如果未指定SCROLL,则NEXT是惟一支持的提取选项。

select_statement:定义游标结果集的标准SELECT语句。在游标声明的select_statement内不允许使用关键字COMPUTE、COMPUTE BY、FOR BROWSE和INTO

READ ONLY:表明不允许游标内的数据被更新,尽管在默认状态下游标是允许更新的。在UPDATE或DELETE语句的WHERE CURRENT OF子句中不允许引用游标。

UPDATE [ OF column_name [ ,...n ] ]:定义游标内可更新的列。如果指定OF column_name [,...n]参数,则只允许修改所列出的列。如果在UPDATE中未指定列的列表,则可以更新所有列。

2)SQL Server扩展格式


[ LOCAL | GLOBAL ]

[ FORWARD_ONLY | SCROLL ]

[ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ]

[ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ]

[ TYPE_WARNING ]

FOR select_statement

[ FOR UPDATE [ OF column_name [ ,...n ] ] ]

参数说明:

LOCAL:定义游标的作用域仅限在其所在的批处理、存储过程或触发器中。当建立游标在存储过程执行结束后,游标会被自动释放。

GLOBAL:指定该游标的作用域对连接是全局的。在由连接执行的任何存储过程或批处理中,都可以引用该游标名称。该游标仅在脱接时隐性释放。

FORWARD_ONLY:指定游标只能从第一行滚动到最后一行。

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

KEYSET:指定当游标打开时,游标中行的成员资格和顺序已经固定。对行进行惟一标识的键集内置在tempdb内一个称为keyset的表中。对基表中的非键值所做的更改(由游标所有者更改或由其他用户提交)在用户滚动游标时是可视的。其他用户进行的插入是不可视的(不能通过Transact-SQL服 务器游标进行插入)。如果某行已删除,则对该行的提取操作将返回@@FETCH_STATUS值-2。从游标外更新键值类似于删除旧行后接着插入新行的操作。含有新值的行不可视,对含有旧值的行的提取操作将返回@@FETCH_STATUS值-2。如果通过指定WHERE CURRENT OF子句用游标完成更新,则新值可视。

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

FAST_FORWARD:指明一个FORWARD_ONLY、READ_ONLY型游标。

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

OPTIMISTIC:指明在数据被读入游标后,如果游标中某行数据已发生变化,那么对游标数据进行更新或删除可能会导致失败。

TYPE_WARNING:指定如果游标从所请求的类型隐性转换为另一种类型,则给客户端发送警告消息。

使用DECLARE CURSOR语句创建以下几种形式的游标

1)示例:创建一个名为“MyCursor”的标准游标。

DECLARE MyCursor CURSOR FOR

SELECT * FROM 操作员信息表

2)示例:创建一个名为“MyCursor_01”的只读游标。

DECLARE MyCursor_01 CURSOR FOR

SELECT * FROM 操作员信息表

FOR READ ONLY    --只读游标

3)示例:创建一个名为“MyCursor_02”的更新游标

DECLARE MyCursor_02 CURSOR FOR

SELECT 操作员编号,操作员姓名,操作员年龄 FROM 操作员信息表

FOR UPDATE    --更新游标

2.打开游标

打开一个声明的游标使用OPEN命令。

OPEN { { [ GLOBAL ] cursor_name } | cursor_variable_name }

GLOBAL:指定cursor_name为全局游标。

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

cursor_variable_name:游标变量的名称,该名称引用一个游标。

 说 明:如果使用INSENSITIV或STATIC选项声明了游标,那么OPEN将创建一个临时表以保留结果集。如果结果集中任意行的大小超过SQL Server表的最大行大小,OPEN将失败。如果使用KEYSET选项声明了游标,那么OPEN将创建一个临时表以保留键集。临时表存储在tempdb 中

()首先声明一个名为MyCursor_001的游标,然后使用OPEN命令打开该游标。


SELECT 操作员编号,操作员姓名,操作员年龄 FROM 操作员信息表

WHERE 操作员编号 = 'CY20040604006'

OPEN MyCursor_001      --打开游标

3.从游标读取数据

当打开一个游标之后,就可以读取游标中的数据了。可以使用FETCH命令读取游标中的某一行数据。

FETCH

        [ [ NEXT | PRIOR | FIRST | LAST

              | ABSOLUTE { n | @nvar }

              | RELATIVE { n | @nvar }

          ]

          FROM

        ]

{ { [ GLOBAL ] cursor_name } | @cursor_variable_name }

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

()从游标中读取数据

USE 销售管理系统    --引入数据库

DECLARE ReadCursor CURSOR FOR    --声明一个游标

SELECT 操作员编号,操作员姓名,操作员性别,操作员住址

FROM 操作员信息表

OPEN ReadCursor    --打开游标

FETCH NEXT FROM ReadCursor    --执行取数操作

WHILE @@FETCH_STATUS=0    --检查@@FETCH_STATUS,以确定是否还可以继续取数

BEGIN

  FETCH NEXT FROM ReadCursor

END

4.关闭游标

CLOSE { { [ GLOBAL ] cursor_name } | cursor_variable_name }

()声明一个名为“CloseCursor”的游标,并使用Close语句关闭游标。

USE 销售管理系统    --引入数据库

DECLARE CloseCursor Cursor FOR    --声明游标

SELECT * FROM 销售表

FOR READ ONLY

OPEN CloseCursor    --打开游标

CLOSE CloseCursor    --关闭游标

5.释放游标

当游标关闭之后,并没有在内存中释放所占用的系统资源,所以可以使用DEALLOCATE命令删除游标引用。当释放最后的游标引用时,组成该游标的数据结构由SQL Server释放。

DEALLOCATE { { [ GLOBAL ] cursor_name } | @cursor_variable_name }

DEALLOCATE 游标名字    --释放游标