游标说简单点都是设置一个数据表的行指针,然后使用循环等操作数据;


游标主要是用来完成复杂的业务逻辑;

比如sqlserver中树型查询,比如如下业务点
数据表
编号  名称         父编号
1        中国        0
2        上海市    1
3        虹口区    2
4        杨浦区    2        

显示结果
/中国/上海市/虹口区
/中国/上海市/杨浦区
类似这样的业务点,在sqlserver中就可能需要使用游标来做了


eg:


create  
 procedure  
 UpdateValue     
 --存储过程里面放置游标 

 
 
 as 

 
 
 begin 

 
 
   

 
 
  
 declare  
 UpdateCursor  
 cursor     
 --声明一个游标,查询满足条件的数据 

 
 
  
 for  
 select  
 主键,SD_VAL  
 from  
 EQ_SD_D 

 
 
   

 
 
  
 open  
 UpdateCursor     
 --打开 

 
 
   

 
 
  
 declare  
 @id  
 int 
 ,@SD_VAL nvarchar(20)   
 --声明一个变量,用于读取游标中的值 

 
 
  
 fetch  
 next  
 from  
 UpdateCursor  
 into  
 @id,@SD_VAL 

 
 
   

 
 
  
 while <a href= 
 "https://www.baidu.com/s?wd=%40%40fetch_status&tn=44039180_cpr&fenlei=mv6quAkxTZn0IZRqIHckPjm4nH00T1d9PvczmWN9nj9hPjbLnyDk0ZwV5Hcvrjm3rH6sPfKWUMw85HfYnjn4nH6sgvPsT6KdThsqpZwYTjCEQLGCpyw9Uz4Bmy-bIi4WUvYETgN-TLwGUv3EPWfLPHRLnWn3PjfLrj63nW6d"  
 target= 
 "_blank"  
 class= 
 "baidu-highlight" 
 >@@fetch_status</a>=0     
 --循环读取 

 
 
  
 begin 

 
 
  
 update  
 EQ_SD_D  
 set  
 name 
 =@SD_VAL  
 where  
 id=@id 

 
 
  
 fetch  
 next  
 from  
 UpdateCursor  
 into  
 @id,@SD_VAL 

 
 
  
 end 

 
 
   

 
 
  
 close  
 UpdateCursor     
 --关闭 

 
 
   

 
 
  
 deallocate  
 UpdateCursor     
 --删除 

 
 
   

 
 
 end


###################################


游标的使用


 讲了这个多游标的优点,现在我们就亲自来揭开游标的神秘的面纱。


 使用游标的顺序: 声名游标、打开游标、读取数据、关闭游标、删除游标。


1.3.1声明游标


最简单游标声明:DECLARE <游标名>CURSOR FOR<SELECT语句>;


其中select语句可以是简单查询,也可以是复杂的接连查询和嵌套查询


例子:[已表2 AddSalary为例子]


Declare mycursor cursor for select * from AddSalary


这样我就对表AddSalary申明了一个游标mycursor 


【高级备注】


DECLARE <游标名> [INSENSITIVE] [SCROLL] CURSORFOR<SELECT语句>


这里我说一下游标中级应用中的[INSENSITIVE]和[SCROLL]


INSENSITIVE


表明MS SQL SERVER 会将游标定义所选取出来的数据记录存放在一临时表内(建立在tempdb 数据库下)。对该游标的读取操作皆由临时表来应答。因此,对基本表的修改并不影响游标提取的数据,即游标不会随着基本表内容的改变而改变,同时也无法通过游标来更新基本表。如果不使用该保留字,那么对基本表的更新、删除都会反映到游标中。


另外应该指出,当遇到以下情况发生时,游标将自动设定INSENSITIVE 选项。


a.在SELECT 语句中使用DISTINCT、 GROUP BY、 HAVING UNION 语句;


b.使用OUTER JOIN;


c.所选取的任意表没有索引;


d.将实数值当作选取的列。


SCROLL


表明所有的提取操作(如FIRST、 LAST、 PRIOR、 NEXT、 RELATIVE、 ABSOLUTE)都可用。如果不使用该保留字,那么只能进行NEXT 提取操作。由此可见,SCROLL 极大地增加了提取数据的灵活性,可以随意读取结果集中的任一行数据记录,而不必关闭再


重开游标。 


1.3.2 打开游标


非常简单,我们就打开刚才我们声明的游标mycursor


OPEN mycursor 


1.3.3读取数据


FETCH [ NEXT | PRIOR | FIRST | LAST] FROM { 游标名  | @游标变量名 } [ INTO @变量名 [,…] ]


参数说明:


NEXT   取下一行的数据,并把下一行作为当前行(递增)。由于打开游标后,行指针是指向该游标第1行之前,所以第一次执行FETCH NEXT操作将取得游标集中的第1行数据。NEXT为默认的游标提取选项。


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


现在我们就取出mycursor游标的数据吧! 


当游标被打开时,行指针将指向该游标集第1行之前,如果要读取游标集中的第1行数据,必须移动行指针使其指向第1行。就本例而言,可以使用下列操作读取第1行数据:


Eg: Fetch next from mycursor 或则 Fetch first from mycursor


这样我就取出了游标里的数据,但是光光这样可不够,我们还需要将取出的数据赋给变量


--声明2个变量


declare @O_ID NVARCHAR(20)


declare @A_Salary float


--将取出的值传入刚才声明的2个变量


Fetch next from mycursor into @ O_ID,@ A_Salary


 


1.3.4关闭游标


CLOSE mycursor   


         


1.3.5删除游标


DEALLOCATE mycursor         


 


1.3.6 实例训练


**/


CREATE PROCEDURE PK_Test


AS


--声明2个变量


declare @O_ID nvarchar(20)  


declare @A_Salary float

 


--声明一个游标mycursor,select语句中参数的个数必须要和从游标取出的变量名相同


declare mycursor cursor for select O_ID,A_Salary from AddSalary

 


--打开游标


open mycursor

 


--从游标里取出数据赋值到我们刚才声明的2个变量中


fetch next from mycursor into @O_ID,@A_Salary

 


--判断游标的状态


-- 0 fetch语句成功    


---1 fetch语句失败或此行不在结果集中    


---2 被提取的行不存在


while (@@fetch_status=0)


begin

 


--显示出我们每次用游标取出的值


  print '游标成功取出一条数据'


  print @O_ID


  print @A_Salary

 


--用游标去取下一条记录


  fetch next from mycursor into @O_ID,@A_Salary


end


--关闭游标


close mycursor


--撤销游标


DEALLOCATE mycursor 


GO