SQL 服务器:用于更新 table 值的嵌套存储过程

SQL Server : nested stored procedure to update table values

我有一个 table 结构及其数据如下。

CREATE TABLE TestTable 
(
    id INT Identity(1,1) PRIMARY KEY,
    creationTimestamp DATE,
    indexOne INT,
    indexTwo INT
);

INSERT INTO TestTable (creationTimestamp, indexOne, indexTwo) 
VALUES 
(2014-01-10, 100, 0),
(2014-01-11, 100, 0),
(2014-01-12, 100, 0),
(2014-01-13, 152, 2),
(2014-01-14, 152, 2),
(2014-01-15, 152, 2),
(2014-02-12, 152, 2),
(2014-02-13, 152, 2),
(2014-02-14, 333, 4),
(2014-02-15, 333, 4),
(2014-02-16, 333, 4),
(2014-03-10, 333, 4),
(2014-03-11, 333, 4),
(2014-03-12, 333, 4),
(2014-03-13, 333, 4),
(2014-03-14, 333, 4),
(2014-04-20, 500, 7),
(2014-04-21, 500, 7),
(2014-04-22, 500, 7),
(2014-04-23, 500, 7);

当您考虑 indexOne + indexTwo 时,存在重复行。但我需要它们是独一无二的。

因此 indexTwo 必须正确索引如下

(2014-01-10, 100, 0),
(2014-01-11, 100, 1),
(2014-01-12, 100, 2),
(2014-01-13, 152, 0),
(2014-01-14, 152, 1),
(2014-01-15, 152, 2),
(2014-02-12, 152, 3),
(2014-02-13, 152, 4),
(2014-02-14, 333, 0),
(2014-02-15, 333, 1),
(2014-02-16, 333, 2),
(2014-03-10, 333, 3),
(2014-03-11, 333, 4),
(2014-03-12, 333, 5),
(2014-03-13, 333, 6),
(2014-03-14, 333, 7),
(2014-04-20, 500, 0),
(2014-04-21, 500, 1),
(2014-04-22, 500, 2),
(2014-04-23, 500, 3);

我写了下面的存储过程,但不能正常工作

declare @indexOne int, @indexTwo int, @x int
declare c cursor for
select indexOne, indexTwo
from TestTable
group by indexOne, indexTwo 

open c
fetch next from c into @indexOne, @indexTwo
while @@FETCH_STATUS = 0
begin
    set @x = 0;             
    declare @id int

    declare c1 cursor for
    select id
    from TestTable
    where indexOne = @indexOne and indexTwo = @indexTwo
    order by creationTimestamp asc  

    open c1
    fetch next from c1 into @id

    while @@FETCH_STATUS = 0                    
    begin
        UPDATE TestTable SET indexTwo = @x WHERE id = @id   
        set @x = @x + 1 
        fetch next from c1 into @id
    end

    close c1
    deallocate c1
    fetch next from c into @indexOne, @indexTwo

end
close c
deallocate c        

帮我找出为什么这不起作用

您不需要 cursor 即可使用 window function 为每个 creationtimestamp, indexone 生成 indextwo 值。我希望这能完成工作。

Sql Server

UPDATE A 
SET    indexTwo = b.indexTwo  
FROM   testtable a 
       JOIN (SELECT creationTimestamp, indexOne, 
                    Row_number()OVER(partition BY indexone 
                        ORDER BY creationtimestamp)-1 indexTwo  
             FROM   testtable) B 
         ON a.creationtimestamp = b.creationtimestamp 
            AND a.indexone = b.indexone 

SQLFIDDLE DEMO