Reputation: 849
i am using below query to update my all records but it starts update from second row how can i modify it to do changes from 1'st row ?
i am using mssql 2008
i think i can not use @@FETCH_STATUS
as 1'st line as it is global.
thanks in advance
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
Upvotes: 16
Views: 108291
Reputation: 749
***/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
Upvotes: 1
Reputation: 317
Just in case you're not using current of, you can use Row_Number function as a reference to update it.
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;
Upvotes: -2
Reputation: 6095
Cursors are generally not a good solution, so any solution such as @Mikael Eriksson's is potentially better. However if you really have to use a cursor to do an update then you should mark it as insensitive:
DECLARE Employee_Cursor INSENSITIVE CURSOR FOR
SELECT empno FROM emp
I haven't confirmed this on 2008 but certainly on 2005 and below, you can expect all kinds of weirdness if you update the data your cursor is defined against, without marking the cursor as insensitive.
Another option could be to use a temporary table.
Upvotes: 1
Reputation: 139010
It looks like you want to assign an incremented value to empno starting with 10.
You can use a CTE and row_number() to do that. No need for a cursor.
;with C as
(
select empno,
9 + row_number() over(order by (select 1)) as NewEmpNo
from emp
)
update C
set empno = NewEmpNo
You cursor version could look like this to do the same.
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;
Upvotes: 43