什么是游标
结果集,结果集就是 select 查询之后返回的所有行数据的集合。
游标则是处理结果集的一种机制吧,它可以定位到结果集中的某一行,多数据进行读写,也可以移动游标定位到你所需要的行中进行操作数据。
一般复杂的存储过程,都会有游标的出现,他的用处主要有:
定位到结果集中的某一行。对当前位置的数据进行读写。可以对结果集中的数据单独操作,而不是整行执行相同的操作。是面向集合的数据库管理系统和面向行的程序设计之间的桥梁。游标使用三步曲:第一步创建游标,第二步打开游标,第三步使用游标。
游标使用
第一步创建游标
语法
– 声明数据库引用 use 数据库名;go
– 创建游标 declare cursor_name [insensitive] [scroll] cursorfor select_statement[for { read only | update [of column_name [,……n] ] } ];
语法注释
–cursor_name–Transact-SQL 服务器游标定义的名称。cursor_name 必须符合有关标识符的规则。
–insensitive– 定义一个游标,以创建将由该游标使用的数据的临时副本。对游标的所有请求都从 tempdb 中的这一临时表中得到应答;– 因此,在对该游标进行提取操作时返回的数据中不反映对基表所做的修改,并且该游标不允许修改。– 使用 ISO 语法时,如果省略 insensitive,则已提交的(任何用户)对基础表的删除和更新则会反映在后面的提取操作中。
–scroll– 指定所有的提取选项(first、last、prior、next、relative 和 absolute)均可用。如果未在 iso declare cursor 中指定 scroll,则 next 是唯一支持的提取选项。– 如果还指定了 fast_forward,则无法指定 scroll。
–select_statement– 是定义游标结果集的标准 select 语句。在游标声明的 select_statement 中不允许使用关键字 for browse 和 into。– 如果 select_statement 中的子句与所请求的游标类型的功能有冲突,则 SQLServer 会将游标隐式转换为其他类型。
–read only– 禁止通过该游标进行更新。无法在 update 或 delete 语句的 where current of 子句中引用游标。该选项优先于要更新的游标的默认功能。
–update [of column_name [,…n]]– 定义游标中可更新的列。如果指定了 of <column_name> [, <… n>],则只允许修改所列出的列。如果指定了 update,但未指定列的列表,则可以更新所有列。
示例
– 声明数据库引用 use testss;go
– 第一种 ISO 语法 – 游标使用三步曲 – 第一步声明游标 declare synae_cursor_name insensitive scroll cursorfor select id,name from test1for read only;
示例结果
第二步打开游标
语法
open {{ [ global] cursor_name } | cursor_variable_name }
语法解析
–global– 指定 cursor_name 是指全局游标。–cursor_name– 已声明的游标的名称。当同时存在以 cursor_name 作为名称的全局游标和局部游标时,如果指定 global,则 cursor_name 是指全局游标;否则,cursor_name 是指局部游标。–cursor_variable_name– 游标变量的名称,该变量引用一个游标。
示例
open global synae_cursor_name;
示例结果
第三步使用游标
语法
fetch [[ next | prior | first | last | absolute { n | @nvar} | relative {n | @nvar} ] from ] {{ [ global] cursor_name } | @cursor_variable_name } [into @variable_name [ ,…n] ]
语法注释
–next– 紧跟当前行返回结果行,并且当前行递增为返回行。如果 fetch next 为对游标的第一次提取操作,则返回结果集中的第一行。next 为默认的游标提取选项。
–prior– 返回紧邻当前行前面的结果行,并且当前行递减为返回行。如果 fetch prior 为对游标的第一次提取操作,则没有行返回并且游标置于第一行之前。
–first– 返回游标中的第一行并将其作为当前行。
–last– 返回游标中的最后一行并将其作为当前行。
–absolute {n| @nvar}– 如果 n 或 @nvar 为正,则返回从游标起始处开始向后的第 n 行,并将返回行变成新的当前行。– 如果 n 或 @nvar 为负,则返回从游标末尾处开始向前的第 n 行,并将返回行变成新的当前行。– 如果 n 或 @nvar 为 0,则不返回行。n 必须是整数常量,并且 @nvar 必须是 smallint、tinyint 或 int。
–relative {n| @nvar}– 如果 n 或 @nvar 为正,则返回从当前行开始向后的第 n 行,并将返回行变成新的当前行。– 如果 n 或 @nvar 为负,则返回从当前行开始向前的第 n 行,并将返回行变成新的当前行。– 如果 n 或 @nvar 为 0,则返回当前行。在对游标进行第一次提取时,– 如果在将 n 或 @nvar 设置为负数或 0 的情况下指定 fetch relative,则不返回行。n 必须是整数常量,并且 @nvar 必须是 smallint、tinyint 或 int。
–global– 指定 cursor_name 是指全局游标。
–cursor_name– 要从中进行提取的开放游标的名称。当同时存在以 cursor_name 作为名称的全局游标和局部游标时,– 如果指定 global,则 cursor_name 指全局游标,如果未指定 global,则指局部游标。
–@cursor_variable_name– 游标变量名,引用要从中进行提取操作的打开的游标。
–into @variable_name[,…n]– 允许将提取操作的列数据放到局部变量中。列表中的各个变量从左到右与游标结果集中的相应列相关联。– 各变量的数据类型必须与相应的结果集列的数据类型匹配,或是结果集列数据类型所支持的隐式转换。变量的数目必须与游标选择列表中的列数一致。
示例
declare @id nvarchar(50),@name nvarchar(50);fetch last from synae_cursor_name into @id,@name;select @id,@name;
示例结果
游标使用扩展
查看游标
语法
exec sp_cursor_list [@cursor_return =] cursor_variable_name output, [@cursor_scope =] cursor_scope [;]
语法解析
–[@cursor_return=] cursor_variable_name 输出 – 已声明的游标变量的名称。cursor_variable_name 是光标,无默认值。游标是可滚动、动态、只读游标。
–[@cursor_scope=] cursor_scope– 指定要报告的游标级别。cursor_scope 是 int,无默认值,并且可以是下列值之一。–@cursor_scope=1(local)(报告所有本地游标)–@cursor_scope=2(global)(报告所有全局游标) –@cursor_scope=3(global 和 local)(报告本地游标和全局游标)
示例
declare @result cursorexec sp_cursor_list @cursor_return=@result output,@cursor_scope=2;fetch next from @result;
示例结果
关闭游标
语法
close {{ [ global] cursor_name } | cursor_variable_name }
语法解析
–global– 指定 cursor_name 是指全局游标。
–cursor_name– 打开的游标的名称。当同时存在以 cursor_name 作为名称的全局游标和局部游标时,如果指定 global,则 cursor_name 是指全局游标;否则,cursor_name 是指局部游标。
–cursor_variable_name– 与打开的游标关联的游标变量的名称。
示例
close global synae_cursor_name;
示例结果
删除游标
语法
deallocate {{ [ global] cursor_name } | @cursor_variable_name }
语法解析
–cursor_name– 已声明游标的名称。当同时存在以 cursor_name 作为名称的全局游标和局部游标时,如果指定 GLOBAL,则 cursor_name 指全局游标,如果未指定 GLOBAL,则指局部游标。–@cursor_variable_name–cursor 变量的名称。@cursor_variable_name 必须为 cursor 类型。
示例
deallocate global synae_cursor_name;
示例结果