sql server 的游标
Posted 庭明
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sql server 的游标相关的知识,希望对你有一定的参考价值。
-- sql server 中的游标
--声明游标
/*
declare cursorname [insensitive] [scroll] cursor
for <select-查询块>
[for {read only|update[of<列名>[,...,n]]}]
Insensitive 表示把取出来的数据存入一个在tempdb库中创建的临时表,任何通过这个游标进行的操作,都会在这个临时表里进行。所有对基本表的改动都不会在用游标进行的操作中体现出来,不用该关键字,则用户对基本表所进行的任何操作都将在游标中得到体现。
Scroll: 指定所有的提取选项(first,last,prior,wext,relative,absolute)均可用,允许删除和更新(假定没有使用insensitive选项)
for read only :游标只读。不允许通过只读游标进行数据的更新。
for update[of <列名>[,...,n]]:游标是可修改的。定义在这个游标里可以更新的列。如果定义了[of<列名>[,...n]],则只有其中的列可以被修改;否则,游标里的所有列都可以被修改。
*/
declare @tagname nvarchar(max)
declare @max_datetime datetime
declare mycursor cursor
for
select a.tagname,max(isnull(b.DateTime,0))
from tblfminfolive a
left join live_dblink.gb_scada_live.dbo.LiveData b on a.tagname=b.tagname and b.provider=‘TAX‘
group by a.tagname;
-- 打开游标
open mycursor;
-- 提取数据
-- fetch[[next|prior|first|last|absoute n|relative n] from] <游标名> [into @变量名[,...,n]]
fetch next from mycursor into @tagname,@max_datetime;
/*全局变量@@fetch_status表示fetch语句的状态
0 表示提取正常
1 表示已经取到了数据集的末尾
其他值均表明操作出了问题
*/
-- 进入循环
while (@@fetch_status=0)
BEGIN
IF right(@tagname,2) !=‘YL‘
-- 写入flux,PlusTotalFlux,ReverseTotalFlux to 目标表
insert into live_dblink.gb_scada_live.dbo.LiveData(
provider,sitename,tagname,MeterName,DateTime,value)
select ‘TAX‘,b.username,b.tagname,b.MeterName,a.readtime
,case right(@tagname,2)
when ‘SL‘ then a.flux
when ‘ZL‘ then a.plustotalflux
when ‘FL‘ then a.reversetotalflux
end
FROM tblfmreaddata a ,tblfminfolive b
WHERE a.fmaddress+right(@tagname,3)[email protected] and [email protected]
AND a.readtime>@max_datetime
ELSE
--写入 pressure to 目标表
insert into live_dblink.gb_scada_live.dbo.LiveData(
provider,sitename,tagname,MeterName,DateTime,value)
select ‘TAX‘,b.username,b.tagname,b.MeterName,a.readtime,isnull(a.pressure,0)
FROM tblfmreaddatapress a,tblfminfolive b
WHERE a.fmaddress+right(@tagname,3)[email protected] and [email protected]
AND a.readtime>@max_datetime
-- 获取下一条数据
fetch next from mycusor into @tagname,@max_datetime;
END;
-- 关闭游标
close mycursor;
-- 释放游标
deallocate mycursor;
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- 由于sql server 的未知原因,cursor未能成功执行,于是创建临时表,原理类似cursor,如下:
--------------------------------------------------------------------------------
declare @cun int
declare @maxcun int
declare @max_datetime datetime
declare @fmaddress varchar(40)
create table #tmp_fmaddress
(
pid int identity(1,1),
fmaddress varchar(100),
max_datetime datetime
)
insert into #tmp_fmaddress(fmaddress,max_datetime)
select a.fmaddress,max(isnull(b.DateTime,0))
from tblfminfolive a
left join live_dblink.gb_scada_live.dbo.LiveData b on a.tagname=b.tagname and b.provider=‘TAX‘
and b.DateTime>dateadd(day,-2,getdate())
group by a.fmaddress
set @cun=1
select @maxcun=max(pid) from #tmp_fmaddress
-- 进入循环
while @cun<@maxcun+1
BEGIN
select @fmaddress=fmaddress,@max_datetime=max_datetime from #tmp_fmaddress where [email protected]
------流量数据
select fmaddress,readtime,flux,PlusTotalFlux,ReverseTotalFlux
into #temp_flux
FROM tblfmreaddata WHERE [email protected]
AND readtime>@max_datetime
AND readtime>dateadd(day,-2,getdate())
-----压力数据
select fmaddress,readtime, isnull(pressure,0) press
into #temp_press
FROM tblfmreaddatapress WHERE [email protected]
AND readtime>@max_datetime
and readtime>dateadd(day,-2,getdate())
-- 写入flux,PlusTotalFlux,ReverseTotalFlux to 目标表
insert into live_dblink.gb_scada_live.dbo.LiveData(
provider,sitename,tagname,MeterName,DateTime,value)
select ‘TAX‘,b.username,b.tagname,b.MeterName,a.readtime
,case right(b.tagname,2)
when ‘SL‘ then a.flux
when ‘ZL‘ then a.plustotalflux
when ‘FL‘ then a.reversetotalflux
end
FROM #temp_flux a,tblfminfolive b
where a.fmaddress=b.fmaddress and [email protected]+‘_YL‘
-- 写入 pressure
insert into live_dblink.gb_scada_live.dbo.LiveData(
provider,sitename,tagname,MeterName,DateTime,value)
select ‘TAX‘,b.username,b.tagname,b.MeterName,a.readtime,a.press
FROM #temp_press a,tblfminfolive b
where a.fmaddress=b.fmaddress and [email protected]+‘_YL‘
drop table #temp_flux
drop table #temp_press
-- 获取下一条数据
set @[email protected]+1
END
以上是关于sql server 的游标的主要内容,如果未能解决你的问题,请参考以下文章