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 的游标的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server基础之游标

sql server 中游标详解

SQL Server游标

SQL Server 游标

sql server 游标的知识

sql server数据库中用游标进行更新