首页 > 代码库 > t-sql 游标

t-sql 游标

? 游标

     游标可以对一个select的结果集进行处理,或是不需要全部处理,就会返回一个对记录集进行处理之后的结果。

     1、游标实际上是一种能从多条数据记录的结果集中每次提取一条记录的机制。游标可以完成:

          # 允许定位到结果集中的特定行

          # 从结果集的当前位置检索一行或多行数据

          # 支持对结果集中当前位置的进行修改

     由于游标是将记录集进行一条条的操作,所以这样给服务器增加负担,一般在操作复杂的结果集的情况下,才使用游标。SQL Server 2005有三种游标:T-SQL游标、API游标、客户端游标。

 

     2、游标的基本操作

          游标的基本操作有定义游标、打开游标、循环读取游标、关闭游标、删除游标。

     A、 定义游标

declare cursor_name --游标名称cursor [local | global] --全局、局部[forward only | scroll] --游标滚动方式[read_only | scroll_locks | optimistic] --读取方式for select_statements --查询语句[for update | of column_name ...] --修改字段

     参数:

     forward only | scroll:前一个参数,游标只能向后移动;后一个参数,游标可以随意移动

     read_only:只读游标

     scroll_locks:游标锁定,游标在读取时,数据库会将该记录锁定,以便游标完成对记录的操作

     optimistic:该参数不会锁定游标;此时,如果记录被读入游标后,对游标进行更新或删除不会超过

 

     B、 打开游标

          open cursor_name;

          游标打开后,可以使用全局变量@@cursor_rows显示读取记录条数

 

     C、 检索游标

          fetch cursor_name;

          检索方式如下:

             fetch first; 读取第一行

             fetch next; 读取下一行

             fetch prior; 读取上一行

             fetch last; 读取最后一行

             fetch absolute n; 读取某一行

                如果n为正整数,则读取第n条记录

                如果n为负数,则倒数提取第n条记录

                如果n为,则不读取任何记录

             fetch pelative n

                如果n为正整数,则读取上次读取记录之后第n条记录

                如果n为负数,则读取上次读取记录之前第n条记录

                如果n为,则读取上次读取的记录

 

     D、 关闭游标

          close cursor_name;

 

     E、 删除游标

          deallocate cursor_name;

 

     3、游标操作示例

--创建一个游标declare cursor_stu cursor scroll forselect id, name, age from student;--打开游标open cursor_stu;--存储读取的值declare @id int,@name nvarchar(20),@age varchar(20);--读取第一条记录fetch first from cursor_stu into @id, @name, @age;--循环读取游标记录print ‘读取的数据如下:‘;--全局变量while (@@fetch_status = 0)beginprint ‘编号:‘ + convert(char(5), @id) + ‘, 名称:‘ + @name + ‘, 类型:‘ + @age;--继续读取下一条记录fetch next from cursor_stu into @id, @name, @age;end--关闭游标close area_cursor;--删除游标--deallocate area_cursor;
工作上的实例
create PROCEDURE [dbo].[WeekTotalPowerBingTuByWeek]
       @DevName varchar(2000),
       @starttime varchar(200)
AS
BEGIN
	SET NOCOUNT ON;
	--Set @DevName='电表1(DTL1110321471),dianbiao$DTL1110321471;电表2(DTL1110321470),dianbiao$DTL1110321470;'
	Declare @pointID varchar(300)
	Declare @pointName varchar(300)
	Create table #tempTable
	(
	  pointName varchar(200),
	  pointValue float
	)
	create table #tempTables
	(
	   pointID varchar(2000),
	   pointName varchar(2000)
    )
	declare @temp table(col varchar(2000))
	--set @str=replace(@str,'|',',')
	while(len(@DevName)>0)
	begin
	insert into @temp
	select left(@DevName,charindex(';',@DevName)-1)
	set @DevName=stuff(@DevName,1,charindex(';',@DevName),'')
	end

	declare @name varchar(2000)
	declare @value varchar(2000)
	declare cur cursor for  select * from @temp
	open cur--打开游标
	fetch next from cur into @name
				 while @@FETCH_STATUS=0  --判断是否成功获取数据
				 begin
				 declare @str1 varchar(2000)
				 declare @str2 varchar(2000)
				 select @str1=left(@name,charindex(',',@name)-1)
				 select @str2=substring(@name,charindex(',',@name)+1,LEN(@name))
				  insert into #tempTables values (@str2,@str1)
				 fetch next from cur into @name
				 end
				close cur --关闭游标
	deallocate cur
	Declare @starttimes varchar(200)
	Declare @endtime varchar(200)
	select @starttimes=dateadd(day,-datepart(weekday,@starttime)+1,@starttime)--开始时间
	select @endtime=dateadd(day,7-datepart(weekday,@starttime)+2,@starttime)--结束时间
	Declare Cur cursor for
	select pointID,pointName from #tempTables
			open Cur
			fetch next from cur into @pointID,@pointName
			 while @@FETCH_STATUS=0  --判断是否成功获取数据
			 begin
				create table #temp
				(
				   inValue float
				)
				declare @inValue float
				Declare @sql varchar(8000)
				Set @sql='insert into #temp select round(SUM(incrementValue),2) as incrementValue  from TAB_DAY_'+@pointID+'
						  where  GetValueTime > '''+@starttimes+''' and GetValueTime < '''+@endtime+''''
				exec(@sql)
				select @inValue=http://www.mamicode.com/inValue from #temp>

t-sql 游标