如何在SQL中获取游标结果集中行的最新值

如何在SQL中获取游标结果集中行的最新值,sql,sql-server,cursor,Sql,Sql Server,Cursor,我正在使用游标对我在游标的Select语句中使用的同一个表执行某些操作,如下所示 CREATE TABLE #nsn (ID INT IDENTITY(1,1) ,Val1 Varchar(MAx) ,Val2 Varchar(MAx) ) INSERT INTO #nsn(Val1,VAl2) select 'A1','A2' INSERT INTO #nsn(Val1,VAl2) select 'B1','B2' INSERT INTO #nsn(Val1,VAl2) select 'C1

我正在使用游标对我在游标的Select语句中使用的同一个表执行某些操作,如下所示

CREATE TABLE #nsn (ID INT IDENTITY(1,1)
,Val1 Varchar(MAx)
,Val2 Varchar(MAx)
)

INSERT INTO #nsn(Val1,VAl2) select 'A1','A2'
INSERT INTO #nsn(Val1,VAl2) select 'B1','B2'
INSERT INTO #nsn(Val1,VAl2) select 'C1','C2'
INSERT INTO #nsn(Val1,VAl2) select 'D1','D2'
INSERT INTO #nsn(Val1,VAl2) select 'E1','F2'

SELECT * From #nsn
ID  Val1    VAl2
1|  A1  |   A2
2|  B1  |   B2
3|  C1  |   C2
4|  D1  |   D2
5|  E1  |   F2
ID  Val1    VAl2
1|  A1  |   A2
2|  B1  |   B2-A1-A2
3|  C1  |   C2-B1-B2-A1-A2
4|  D1  |   D2-C1-C2-B1-B2-A1-A2
5|  E1  |   F2-D1-D2-C1-C2-B1-B2-A1-A2
使用光标更新Val2列

DECLARE @ID INT 
        ,@Val1 Varchar(MAx)
        ,@Val2 Varchar(MAx)

DECLARE cursor_Latest CURSOR
FOR SELECT  ID,Val1,Val2
    FROM    #nsn 
    ORder by 1 asc
OPEN cursor_Latest
FETCH NEXT FROM cursor_Latest INTO  @ID , @Val1 ,@Val2
WHILE (@@FETCH_STATUS <> -1)
BEGIN
    UPDATE #nsn
    SET Val2 = Val2 +'-'+ @Val1 +'-'+@Val2
    WHERE ID = @ID+1

    FETCH NEXT FROM cursor_Latest INTO  @ID , @Val1 ,@Val2
END
close cursor_Latest
DEALLOCATE cursor_Latest
但我期待的结果如下:

CREATE TABLE #nsn (ID INT IDENTITY(1,1)
,Val1 Varchar(MAx)
,Val2 Varchar(MAx)
)

INSERT INTO #nsn(Val1,VAl2) select 'A1','A2'
INSERT INTO #nsn(Val1,VAl2) select 'B1','B2'
INSERT INTO #nsn(Val1,VAl2) select 'C1','C2'
INSERT INTO #nsn(Val1,VAl2) select 'D1','D2'
INSERT INTO #nsn(Val1,VAl2) select 'E1','F2'

SELECT * From #nsn
ID  Val1    VAl2
1|  A1  |   A2
2|  B1  |   B2
3|  C1  |   C2
4|  D1  |   D2
5|  E1  |   F2
ID  Val1    VAl2
1|  A1  |   A2
2|  B1  |   B2-A1-A2
3|  C1  |   C2-B1-B2-A1-A2
4|  D1  |   D2-C1-C2-B1-B2-A1-A2
5|  E1  |   F2-D1-D2-C1-C2-B1-B2-A1-A2
那么这个代码有什么错误吗?或 游标是否有任何记录存储,因为它没有获取新行的最新更新值


提前感谢您的帮助。

尝试在游标声明中指定动态选项

DECLARE cursor_Latest CURSOR DYNAMIC
网上图书说: 定义一个游标,该游标反映在光标周围滚动时对其结果集中的行所做的所有数据更改。每次提取时,行的数据值、顺序和成员资格都可能发生变化


换言之,每次提取时都会再次提取数据,它将反映刚才所做的更改。因此,VAL2将获得您想要的适当连接。

为了达到您的预期结果,您应该尝试以下方法

DECLARE @ID       INT
       ,@Val1     VARCHAR(MAX)
       ,@Val2     VARCHAR(MAX)

DECLARE cursor_Latest CURSOR  
FOR
    SELECT ID,Val1,Val2 FROM   #nsn
    ORDER BY 1 ASC

OPEN cursor_Latest
FETCH NEXT FROM cursor_Latest INTO  @ID , @Val1 ,@Val2
WHILE (@@FETCH_STATUS<>-1)
BEGIN
    IF @ID=1
    BEGIN
        UPDATE #nsn
        SET    Val2     = Val2+'-'+@Val1+'-'+@Val2
        WHERE  ID       = @ID+1
    END
    ELSE
    BEGIN
        UPDATE #nsn
        SET    Val2   = Val2+'-'+@Val1+'-'+@Val2+'-'+( SELECT Val1+'-'+Val2 FROM   #nsn WHERE  ID     = @ID-1)
        WHERE  ID                = @ID+1
    END 

    FETCH NEXT FROM cursor_Latest INTO @ID , @Val1 ,@Val2
END
CLOSE cursor_Latest
DEALLOCATE cursor_Latest

SELECT * FROM   #nsn
DROP TABLE  #nsn

您可以在不使用游标的情况下使用for xml来连接相关子查询中的值

update N1
set Val2 = (
           select case when N1.ID = N2.ID then '' else '-' + N2.Val1 end + '-' + N2.Val2
           from #nsn as N2
           where N1.ID >= N2.ID
           order by N2.ID desc
           for xml path(''), type
           ).value('substring(text()[1], 2)', 'varchar(max)')
from #nsn as N1

这是一个三角形的自连接,所以如果你有很多行,光标版本可能是更快的选择。试试看。

声明@ID INT、@Val1 VarcharMAx、@Val2 VarcharMAx、@v1 VarcharMAx
CREATE TABLE #nsn (ID INT IDENTITY(1,1),Val1 Varchar(MAx),Val2 Varchar(MAx)) 

INSERT INTO #nsn(Val1,VAl2) select 'A1','A2'
INSERT INTO #nsn(Val1,VAl2) select 'B1','B2'
INSERT INTO #nsn(Val1,VAl2) select 'C1','C2'
INSERT INTO #nsn(Val1,VAl2) select 'D1','D2'
INSERT INTO #nsn(Val1,VAl2) select 'E1','F2'

DECLARE  @ID INT 
        ,@Val1 Varchar(MAx)
        ,@Val2 Varchar(MAx)
        ,@v1 Varchar(MAx)
        ,@v2 Varchar(MAx)
        ,@t Varchar(MAx),@val varchar(max)
        set @ID=1 


while @ID<=(select count(*) from #nsn)
begin
select @v1=val1,@v2=val2 from #nsn where ID=@ID
select @Val1=val1,@Val2=val2 from #nsn where id=@ID+1
update #nsn set val2= case when @val is not null then  @Val2+'-'+@v1+'-'+@val else @Val2+'-'+@v1+'-'+@v2  end  where id=@ID+1
select  @val=@Val2+'-'+@v1+'-'+@v2
set @ID=@ID+1
end
SELECT * From #nsn
,@v2 VarcharMAx,@t VarcharMAx,@val VarcharMAx 设置@ID=1
虽然@IDThank,但我在游标块中有一些不同的逻辑和计算过程,基于此我正在更新此表行。谢谢,我尝试过,但它不起作用。它给出了相同的输出