使用具有循环

时间:2016-08-29 08:51:40

标签: sql-server

我有一张桌子

| code | descd | slnum |
|------|-------|-------|
| 10   | a     | 0     |
| 10   | b     | 0     |
| 12   | c     | 0     |
| 12   | d     | 0     |
| 11   | e     | 0     |
| 11   | f     | 0     |

我必须使用带有循环的游标

更新这样的slnum列
| code | descd | slnum |
|------|-------|-------|
| 10   | a     | 1     |
| 10   | b     | 2     |
| 12   | c     | 1     |
| 12   | d     | 2     |
| 11   | e     | 1     |
| 12   | f     | 3     |

如何解决这个问题?我试过这样但是没有给我正确的输出

DECLARE @value INT  
DECLARE @s INT=1   

DECLARE scursor  CURSOR FOR  

SELECT slnum  
FROM trec   
for update of slnum  

OPEN scursor  

FETCH NEXT FROM scursor  
INTO @value  

WHILE @@FETCH_STATUS = 0  
BEGIN  
    if exists(select * from trec) -- missing  
    begin  
    update trec  
    set slnum=@s  
    where current of scursor  
    select @s=@s+1  
    end  
    else   
    begin  
    update trec  
    set slnum=@s          
    where current of scursor  
    end  
    FETCH NEXT FROM scursor INTO @value  
END  

CLOSE scursor  
DEALLOCATE scursor  

4 个答案:

答案 0 :(得分:2)

我不知道您是否必须使用光标,但使用UPDATE,您的查询对于ROW_NUMBER加入的人来说是一个死的铃声:

UPDATE t1
SET
    slnum = t2.slnum
FROM
    yourTable t1
INNER JOIN
(
    SELECT code,
           descd,
           ROW_NUMBER() OVER(PARTITION BY code ORDER BY descd) AS slnum
    FROM yourTable
) t2
    ON t1.code = t2.code AND
       t1.descd = t2.descd

答案 1 :(得分:0)

DECLARE @descd varchar(3)  
DECLARE @s int   

DECLARE scursor cursor local static forward_only read_only for   
SELECT descd,  
       row_number() over(partition by code order by descd) as s  
FROM trec  

OPEN scursor  

FETCH NEXT FROM scursor  
INTO @descd, @s  

WHILE @@fetch_status = 0  
BEGIN  
    update trec  
    set slnum = @s  
    where descd = @descd  

  FETCH NEXT FROM scursor  
  INTO @descd, @s  
END  

CLOSE scursor  
DEALLOCATE scursor  

答案 2 :(得分:0)

DECLARE @descd varchar(3)  
DECLARE @codeOld int   
DECLARE @code int  
DECLARE @slnum int = 1                     

DECLARE cur2 CURSOR  
  FOR  
    SELECT descd,code  
    FROM trec      
    ORDER BY code,descd          
  OPEN cur2  
  FETCH NEXT FROM cur2 INTO @descd, @code  
  WHILE @@FETCH_STATUS = 0  
    BEGIN    

       if @codeold = @code
      begin
        set @slnum = @slnum+1
      end
      else
      begin
        set @slnum = 1  
      end

      UPDATE trec
      SET slnum = @slnum                  
      WHERE descd = @descd              
      SET @codeOld = @code                   

      FETCH NEXT FROM cur2 INTO @descd, @code 
    END

  CLOSE cur2
  DEALLOCATE cur2

答案 3 :(得分:0)

DECLARE @descd varchar(3)
DECLARE @codeOld int 
DECLARE @code int
DECLARE @slnum int = 1                   

DECLARE cur2 CURSOR
  FOR
    SELECT descd,code
    FROM trec    
    ORDER BY code,descd        
  OPEN cur2
  FETCH NEXT FROM cur2 INTO @descd, @code
  WHILE @@FETCH_STATUS = 0
    BEGIN  

      SELECT @slnum = CASE 
      WHEN @codeOld = @code 
      THEN @slnum + 1 
      ELSE 1 
      END

      UPDATE trec
      SET slnum = @slnum                  
      WHERE descd = @descd              
      SET @codeOld = @code  

      FETCH NEXT FROM cur2 INTO @descd, @code      
    END

  CLOSE cur2
  DEALLOCATE cur2