游标更新删除当前数据,SqlServer游标使用
- 定位到结果集中的某一行。
- 对当前位置的数据进行读写。
- 可以对结果集中的数据单独操作,而不是整行执行相同的操作。
- 是面向集合的数据库管理系统和面向行的程序设计之间的桥梁。
- 静态游标: 静态游标的结果集,在游标打开的时候建立在TempDB中,不论你在操作游标的时候,如何操作数据库,游标中的数据集都不会变。例如你在游标打开的时候,对游标查询的数据表数据进行增删改,操作之后,静态游标中select的数据依旧显示的为没有操作之前的数据。如果想与操作之后的数据一致,则重新关闭打开游标即可。
- 动态游标:这个则与静态游标相对,滚动游标时,动态游标反应结果集中的所有更改。结果集中的行数据值、顺序和成员在每次提取时都会变化。所有用户做的增删改语句通过游标均可见。如果使用API函数或T-SQL Where Current of子句通过游标进行更新,他们将立即可见。在游标外部所做的更新直到提交时才可见。
- 只进游标:只进游标不支持滚动,只支持从头到尾顺序提取数据,数据库执行增删改,在提取时是可见的,但由于该游标只能进不能向后滚动,所以在行提取后对行做增删改是不可见的。
- 键集驱动游标:打开键集驱动游标时,该有表中的各个成员身份和顺序是固定的。打开游标时,结果集这些行数据被一组唯一标识符标识,被标识的列做删改时,用户滚动游标是可见的,如果没被标识的列增该,则不可见,比如insert一条数据,是不可见的,若可见,须关闭重新打开游标。
1.声明游标,语法
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游标。如果指定啦Scroll或For_Update,就不能指定他啦。
- Read_Only:不能通过游标对数据进行删改。
- Scroll_Locks:将行读入游标是,锁定这些行,确保删除或更新一定会成功。如果指定啦Fast_Forward或Static,就不能指定他啦。
- Optimistic:指定如果行自读入游标以来已得到更新,则通过游标进行的定位更新或定位删除不成功。当将行读入游标时,sqlserver不锁定行,它改用timestamp列值的比较结果来确定行读入游标后是否发生了修改,如果表不行timestamp列,它改用校验和值进行确定。如果已修改改行,则尝试进行的定位更新或删除将失败。如果指定啦Fast_Forward,则不能指定他。
- Type_Warning:指定将游标从所请求的类型隐式转换为另一种类型时向客户端发送警告信息。
- For Update[of column_name ,....] :定义游标中可更新的列。
--提取游标语法
Fetch [ [Next|prior|Frist|Last|Absoute n|Relative n ] from ] [Global] cursor_name [into @variable_name[,....]]
- Frist:结果集的第一行
- Prior:当前位置的上一行
- Next:当前位置的下一行
- Last:最后一行
- Absoute n:从游标的第一行开始数,第n行。
- Relative n:从当前位置数,第n行。
- Into @variable_name[,...] : 将提取到的数据存放到变量variable_name中。
fetch first from orderNum_02_cursor fetch relative 3 from orderNum_02_cursor fetch next from orderNum_02_cursor fetch absolute 4 from orderNum_02_cursor fetch next from orderNum_02_cursor fetch last from orderNum_02_cursor fetch prior from orderNum_02_cursor select * from bigorder where orderNum='ZEORD003402'
declare @OrderId int fetch absolute 3 from orderNum_02_cursor into @OrderId select @OrderId as id select * from bigorder where orderNum='ZEORD003402'
declare @OrderId int fetch absolute 3 from orderNum_02_cursor into @OrderId while @@fetch_status=0 --提取成功,进行下一条数据的提取操作 begin select @OrderId as id fetch next from orderNum_02_cursor into @OrderId --移动游标 end
---游标更新删除当前数据 ---1.声明游标
declare orderNum_03_cursor cursor scroll for select OrderId ,userId from bigorder where orderNum='ZEORD003402' --2.打开游标 open orderNum_03_cursor --3.声明游标提取数据所要存放的变量 declare @OrderId int ,@userId varchar(15) --4.定位游标到哪一行 fetch First from orderNum_03_cursor into @OrderId,@userId --into的变量数量必须与游标查询结果集的列数相同 while @@fetch_status=0 --提取成功,进行下一条数据的提取操作 begin if @OrderId=122182 begin Update bigorder Set UserId='123' Where Current of orderNum_03_cursor --修改当前行 end if @OrderId=154074 begin Delete bigorder Where Current of orderNum_03_cursor --删除当前行 end fetch next from orderNum_03_cursor into @OrderId ,@userId --移动游标 end
--关闭游标语法
close [ Global ] cursor_name | cursor_variable_name --关闭游标 close orderNum_03_cursor
--释放游标语法
deallocate [ Global ] cursor_name | cursor_variable_name --释放游标 deallocate orderNum_03_cursor