如何使用游标更新记录

时间:2011-12-28 06:29:31

标签: sql sql-server sql-server-2008

我使用以下查询来更新我的所有记录,但它从第二行开始更新 如何修改它以从第1行进行更改?

我正在使用 mssql 2008

我认为我不能将@@FETCH_STATUS用作第1行,因为它是全球性的。

提前致谢

use vivdb

DECLARE @empno as int;
select @empno = 10;

DECLARE Employee_Cursor CURSOR FOR select * from emp
OPEN Employee_Cursor;

FETCH NEXT from Employee_Cursor

WHILE @@FETCH_STATUS = 0
   BEGIN

      update emp set empno = @empno;
      select @empno = @empno+1;

     FETCH NEXT from Employee_Cursor
   END;

CLOSE Employee_Cursor;
DEALLOCATE Employee_Cursor;
GO

4 个答案:

答案 0 :(得分:8)

看起来您想要为从10开始的empno分配增量值。

您可以使用CTE和row_number()来执行此操作。不需要光标。

;with C as
(
  select empno,
         9 + row_number() over(order by (select 1)) as NewEmpNo
  from emp       
)
update C
set empno = NewEmpNo

你的游标版本可能看起来像这样做。

DECLARE @empno AS INT;
DECLARE @CurEmpNo AS INT;

SELECT @empno = 10;

DECLARE employee_cursor CURSOR FOR
  SELECT empno
  FROM   emp

OPEN employee_cursor;

FETCH NEXT FROM employee_cursor INTO @CurEmpNo

WHILE @@FETCH_STATUS = 0
  BEGIN
      UPDATE emp
      SET    empno = @empno
      WHERE  CURRENT OF employee_cursor;

      SELECT @empno = @empno + 1;

      FETCH NEXT FROM employee_cursor INTO @CurEmpNo
  END;

CLOSE employee_cursor;

DEALLOCATE employee_cursor;  

答案 1 :(得分:0)

游标通常不是一个好的解决方案,因此@Mikael Eriksson的任何解决方案都可能更好。但是,如果您真的必须使用游标进行更新,那么您应该将其标记为不敏感:

DECLARE Employee_Cursor INSENSITIVE CURSOR FOR
SELECT empno FROM emp

我在2008年没有证实这一点,但肯定在2005年及以后,如果更新光标定义的数据,你可以期待各种奇怪,而不会将光标标记为不敏感。

另一种选择可能是使用临时表。

答案 2 :(得分:0)

只要您不使用最新版本,就可以使用 Row_Number 函数作为更新的参考。

DECLARE @empno AS INT;
DECLARE @CurEmpNo AS INT;

SELECT @empno = 10;

DECLARE employee_cursor CURSOR FOR
  SELECT empno
  FROM   emp

OPEN employee_cursor;

FETCH NEXT FROM employee_cursor

WHILE @@FETCH_STATUS = 0
  BEGIN
      SELECT @CurEmpNo = @CurEmpNo + 1, @empno = @empno + 1

      ;With C As(
           Select empno, 
           ROW_NUMBER() OVER (ORDER BY empno DESC) AS RowNo
           From emp
      )

      UPDATE C 
      SET    empno = @empno
      WHERE  RowNo = @CurEmpNo;

      FETCH NEXT FROM employee_cursor 
  END;

CLOSE employee_cursor;

DEALLOCATE employee_cursor;

答案 3 :(得分:0)

***/Update Multiple Record Using Curser In SQl /***

  CREATE PROCEDURE [dbo].[SP_UpdateDatausingCursor_Update]
    (
    @Msg NVARCHAR(MAX)=null OUTPUT
    )
    AS
    BEGIN 

    /**Declare Cursor**/
    DECLARE @TCursor CURSOR

    /**Declare Cursor**/

    DECLARE @Code bigint=null,@ComId int=null,@JDate DATE=null,@LDate DATE=null

    /**Creating TempDetails Table**/
    CREATE TABLE #TempDetails
    (Code BIGINT,ComId INT,JDate DATE,LDate DATE)
    /**Creating TempDetails Table**/

    INSERT INTO #TempDetails(Code,ComId,JDate,LDate)
    (
    SELECT DISTINCT Code,ComId,JDate,LDate FROM tbl_FormRecord /*GEt Data From table*/
    )

    SET @TCursor =CURSOR FOR SELECT Code,ComId,JDate,LDate FROM #TempDetails
    OPEN @TCursor 
    FETCH NEXT FROM @TCursor INTO @Code,@ComId,@JDate,@LDate
    WHILE @@FETCH_STATUS=0
            BEGIN
                    UPDATE tbl_Form2
                    SEt JDate=@JDate,
                    LDate=@LDate
                    WHERE Code=@Code AND ComId=@ComId   

                    FETCH NEXT FROM @TCursor INTO @Code,@ComId,@JDate,@LDate
            END
            SET @Msg='DATE Updated Successfully.'
    DEALLOCATE @TCursor
    SELECT * FROM #TempDetails
    DROP TABLE #TempDetails
    END