cursor用于更新前一行和当前行中的值的行

时间:2010-11-03 17:25:14

标签: sql sql-server-2005 select cursor

查询作家,

我有一张表格如下:

myTable t1
col2 col3
 2    1
 3    0
 4    0
 5    0
 6    0

我想更新col3上的每个零,前一行中col3的值加上当前行中col2的值。所以我的表格会如下:

myTable t1
col2 col3
 2    1 
 3    4  (1+3)
 4    8  (4+4)
 5    13 (5+8) 
 6    19 (6+13)

我错过了这里的逻辑,也许是短视。我用光标尝试如下:

DECLARE @var3 FLOAT

DECLARE cursor3 CURSOR FOR
SELECT col2, col3 FROM table1
FOR UPDATE OF col3
OPEN cursor3


FETCH FIRST FROM cursor3
WHILE (@@FETCH_STATUS > -1)
BEGIN
 UPDATE @table1
 SET col3 = isnull(@var3, 0) + isnull(col2, 0)
 WHERE CURRENT OF cursor3
 FETCH NEXT FROM cursor3 INTO @var3
END

但这是错的。 有什么想法吗?

提前致谢。

4 个答案:

答案 0 :(得分:9)

好的,试试这个。

CREATE TABLE MyTable (Id INT Identity, Col2 int, Col3 int)

INSERT INTO MyTable (Col2, Col3)
VALUES (2,1), (3,0), (4,0),(5,0),(6,0)

SELECT * from MyTable

WHILE (SELECT COUNT(*) FROM MyTable WHERE Col3=0) > 0
BEGIN
    UPDATE TOP (1) MyTable
    SET CoL3 = (Mytable.col2 + (select col3 from mytable t2 where (t2.id = mytable.id-1)))
    WHERE Col3 = 0
END

SELECT * from MyTable

在大多数情况下使用WHILE循环,它应该比光标快。

答案 1 :(得分:2)

我在表格中添加了一个标识列,最后使用了这样的代码:

DECLARE @saldo_Q_previous FLOAT
DECLARE @ID INTEGER

DECLARE cursor3 CURSOR FOR
SELECT ID FROM @myTable
FOR UPDATE OF col2
OPEN cursor3

FETCH NEXT FROM cursor3 INTO @ID
FETCH NEXT FROM cursor3 INTO @ID

WHILE (@@FETCH_STATUS > -1)
BEGIN

    SET @col2_previous = ISNULL((SELECT TOP 1 col2 FROM @myTable WHERE ID < @ID ORDER BY ID DESC), 0)
    SET @vrQ = ISNULL((SELECT TOP 1 vr_Q FROM @myTable WHERE ID < @ID ORDER BY ID DESC), 0)

    UPDATE @myTable
    SET col2 = isnull(@col2_previous, 0) + isnull(vrMov_Q, 0)
    WHERE CURRENT OF cursor3

    FETCH NEXT FROM cursor3 INTO @ID
END

CLOSE cursor3
DEALLOCATE cursor3

它解决了我的问题。谢谢大家。

答案 2 :(得分:0)

这是一个UPDATE语句,它使用公用表表达式(CTE)来更新数据。

WITH myTable2 AS
    (
    SELECT col2, col3, ROW_NUMBER() OVER (ORDER BY col2) AS sequence
    FROM myTable
    ),
  newTable AS
    (
    SELECT t1.col2, SUM(t2.col2) - SUM(t2.col3) AS col3
    FROM myTable2 t1
    LEFT OUTER JOIN myTable2 t2 ON t1.sequence >= t2.sequence
    GROUP BY t1.col2
    )

UPDATE myTable
SET col3 = newTable.col3
FROM myTable
JOIN newTable on myTable.col2 = newTable.col2
;

答案 3 :(得分:0)

FWIW使用CURSOR的主要原因是,如果不这样做,会对你的rdbms造成太大的打击。你几乎总是可以使用WHILE循环而不是CURSOR;一次处理一条记录;当你出于某种原因需要迭代大量记录时,它会非常有用... CURSOR操作比等效的SET操作指数级更高效。

所以一般来说,它取决于速度和速度。开销与效率......

CURSORS几乎是最慢的方式,但开销最少,即使在MSSQL 2012中仍然有用......