Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use cursor to update record

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
like image 318
vivek Avatar asked Dec 28 '11 06:12

vivek


People also ask

Can we update using cursor?

You can update rows of data as you retrieve them by using a cursor. On the select-statement, use FOR UPDATE OF followed by a list of columns that may be updated. Then use the cursor-controlled UPDATE statement. The WHERE CURRENT OF clause names the cursor that points to the row you want to update.

How do I update my cursor?

You must include the FOR UPDATE clause in the cursor query so that the rows are locked on OPEN. Use cursors to update or delete the current row. Include the FOR UPDATE clause in the cursor query to lock the rows first. Use the WHERE CURRENT OF clause to reference the current row from an explicit cursor.

What is for update clause in cursors?

The FOR UPDATE clause is an optional part of a SELECT statement. Cursors are read-only by default. The FOR UPDATE clause specifies that the cursor should be updatable, and enforces a check during compilation that the SELECT statement meets the requirements for an updatable cursor.

How do you update an existing record in SQL?

The UPDATE command in SQL is used to modify or change the existing records in a table. If we want to update a particular value, we use the WHERE clause along with the UPDATE clause. If you do not use the WHERE clause, all the rows will be affected.


2 Answers

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;  
like image 84
Mikael Eriksson Avatar answered Nov 04 '22 00:11

Mikael Eriksson


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.

like image 22
s1mm0t Avatar answered Nov 04 '22 00:11

s1mm0t