SQL之游标

一、游标的概念

    游标是一组结果集,就是select查询之后返回的所有行数据的集合。游标其实可以理解成一个定义在特定数据集上的指针,我们可以控制这个指针遍历数据集,或者仅仅是指向特定的行。

游标(Cursor)的优点:

  • 是处理数据的一种方法。
  • 它可以定位到结果集中的某一行,对数据进行读写。
  • 也可以移动游标定位到你需要的行中进行数据操作。
  • 是面向集合的数据库管理系统和面向行的程序设计之间的桥梁
  • 作为一个备用方式,当我们穷尽了while循环,子查询,临时表,表变量,自建函数或其他方式仍然无法实现某些查询的时候用游标来实现。

游标(Cursor)的缺点:

  • 游标会吃更多的内存,减少可用的并发,占用宽带,锁定资源还有更多的代码量。

一个完整的游标由5部分组成:

(1)声明游标 (2)打开游标 (3)从一个游标中查找信息 (4)关闭游标 (5)释放游标

一、声明游标

declare cursor_name [global/local] cursor for
select * from table1
go

--一个例子(定义后直接赋值):
DECLARE cursor_name CURSOR FOR
SELECT * FROM TABLE1

--用GO结束上面作用域
GO

一些参数解释:

cursor_name:游标名称。
Local:作用域为局部,只在定义它的批处理,存储过程或触发器中有效。
Global:作用域为全局,由连接执行的任何存储过程或批处理中,都可以引用该游标。

全局游标global在批处理结束后依然有效,局部游标local在批处理结束后被隐式释放,无法在其他批处理中调用,默认是global

声明游标还有更复杂的参数(完整的声明形式):

DECLARE cursor_name CURSOR [ 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 ] ] ]

cursor_name:游标名称。
Local:作用域为局部,只在定义它的批处理,存储过程或触发器中有效。
Global:作用域为全局,由连接执行的任何存储过程或批处理中,都可以引用该游标。
[Local | Global]:默认为local。
Forward_Only:指定游标智能从第一行滚到最后一行。 Fetch Next是唯一支持的提取选项。如果在指定Forward_Only时不指定Static、KeySet、Dynamic关键字,默认为Dynamic游标。如果Forward_Only和Scroll没有指定,Static、KeySet、Dynamic游标默认为Scroll,Fast_Forward默认为Forward_Only
Static:静态游标
KeySet:键集游标
Dynamic:动态游标,不支持Absolute提取选项
Fast_Forward:指定启用了性能优化的Forward_Only、Read_Only游标。
Read_Only:意味着声明的游标只能读取数据,游标不能做任何更新操作
Scroll_Locks:将读入游标的所有数据进行锁定,防止其他程序进行更改,以确保更新的绝对成功
Optimistic:是相对比较好的一个选择,OPTIMISTIC不锁定任何数据,当需要在游标中更新数据时,如果底层表数据更新,则游标内数据更新不成功,如果,底层表数据未更新,则游标内表数据可以更新。
Type_Warning:指定将游标从所请求的类型隐式转换为另一种类型时向客户端发送警告信息。
For Update[of column_name ,....] :定义游标中可更新的列。

二、打开游标

 open cursor_name 注意当全局游标和局部游标变量重名时,默认会打开局部变量游标

全局游标在批处理结束后依然有效
局部游标在批处理结束后被隐式释放,无法再其他批处理中引用

三、从一个游标中查找信息 

Fetch
[ [Next|prior|Frist|Last|Absoute n|Relative n ]
from
[Global] cursor_name
into @variable_name[,....]]

一个例子(取当前位置的下一行,将提取到的数据存放到变量id,name中):

fetch next from cursor_name into @id,@name

一些参数解释:

Frist:结果集的第一行
Prior:当前位置的上一行
Next:当前位置的下一行
Last:最后一行
Absoute n:从游标的第一行开始数,第n行。
Relative n:从相对当前位置数,第n行。(n为负数向前数,否则向后)
Into @variable_name[,...] : 将提取到的数据存放到变量variable_name中。
注意:    对于未指定SCROLL选项的游标来说,只支持NEXT取值.

四、关闭游标

close+游标名称

五、释放游标

deallocate+游标名称

下面是一个完整的例子()

表数据:

处理过程:

--声明游标
declare test_Cursortable3 CURSOR FOR
SELECT id,NAME FROM TABLE3
--打开游标
OPEN test_Cursortable3
--声明游标提取变量所要存放的变量
declare @id int,@name varchar(20)
--定位游标到哪一行
fetch next from test_Cursortable3 into @id,@name    --into的变量数量必须需与游标查询结果的列数相同
--fetch FIRST from test_Cursortable3 into @id,@name
while @@FETCH_STATUS=0  --提取成功,进行下一条数据的提取操作
begin
    if @id=2
    begin
    Update TABLE3 Set sex='0' Where Current of test_Cursortable3 --更新当前行
    end
    if  @id=10
    begin
    delete TABLE3 where current  of test_Cursortable3    --删除当前行
    end
fetch next from test_Cursortable3 into @id,@name    --移动游标
end
--关闭游标
close    test_Cursortable3
--释放游标
deallocate test_Cursortable3

处理结果:

最后,使用游标时注意事项:

  • 如果能不用游标,尽量不要使用游标。
  • 用过之后一定要关闭和释放。
  • 尽量不要在大量数据上定义游标(一万行以上)。
  • 尽量不要使用游标上更新数据。
  • 尽量不要使用insensitive, static和keyset这些参数定义游标。
  • 如果可以,尽量使用FAST_FORWARD关键字定义游标。
  • 如果只对数据进行读取,当读取时只用到FETCH NEXT选项,则最好使用FORWARD_ONLY参数

猜你喜欢

转载自www.cnblogs.com/xiao02fang/p/12567687.html