Update data via cursor in another table

Asked

Viewed 54 times

0

I designed the cursor below to update contacts. It runs successfully, however it does not provide the expected result.

DECLARE @sequencia int,
@codigoOld int,
@telefoneOld nvarchar(5),
@timestampOld datetime, 
@vetorOld int,
@codigoNew int,
@telefoneNew nvarchar(5),
@timestampNew datetime,
@vetorNew int,
@codigo INT ,
@telefone INT; 

DECLARE CONFLITO_CURSOR CURSOR FOR SELECT sequencia,codigoOld,
telefoneOld,timestampOld,vetorOld,codigoNew,telefoneNew,timestampNew,
vetorNew FROM registoOperacoes ORDER BY sequencia ASC 

OPEN CONFLITO_CURSOR

FETCH NEXT FROM CONFLITO_CURSOR INTO @sequencia,@codigoOld,@telefoneOld,
@timestampOld,@vetorOld,@codigoNew,@telefoneNew,@timestampNew,@vetorNew

WHILE (@@FETCH_STATUS=0)
 begin 

    DECLARE SERVIDOR_CURSOR CURSOR FOR SELECT codigo,telefone FROM servidor , registoOperacoes WHERE servidor.codigo=@codigoNew
    OPEN SERVIDOR_CURSOR
    FETCH NEXT FROM SERVIDOR_CURSOR INTO  @codigo,@telefone

    WHILE (@@FETCH_STATUS=0)
    BEGIN 
        IF @timestampOld<@timestampNew
        print N'Código: '+CAST(@codigo AS NVARCHAR(10))+' Telefone: '+CAST(@telefone AS NVARCHAR(15));
        UPDATE servidor 
        SET codigo=@codigo,telefone=@telefone
        WHERE codigo=@codigo

        FETCH NEXT FROM SERVIDOR_CURSOR INTO  @codigo,@telefone
        END
        CLOSE SERVIDOR_CURSOR
        DEALLOCATE SERVIDOR_CURSOR 
FETCH NEXT FROM CONFLITO_CURSOR INTO @sequencia,@codigoOld,@telefoneOld,@timestampOld,@vetorOld,@codigoNew,@telefoneNew,@timestampNew,@vetorNew
END     
CLOSE CONFLITO_CURSOR
DEALLOCATE CONFLITO_CURSOR
  • Well, what would be the "expected result"?

  • The data would be printed on the screen and would be updated in the server table

1 answer

0

The problem in your script is that each time it runs from FETCH, the value of the variable @@FETCH_STATUS is updated, and this makes it impossible to use nested cursors.

The solution is to assign the value of @@FETCH_STATUS a variable, and use it to check whether the CURSOR still has data to read. In your code, it would be like this for example:

DECLARE @FETCH_PRIMEIRO_CURSOR int
DECLARE @FETCH_SEGUNDO_CURSOR int

FETCH NEXT FROM CONFLITO_CURSOR INTO @sequencia,@codigoOld,@telefoneOld,
@timestampOld,@vetorOld,@codigoNew,@telefoneNew,@timestampNew,@vetorNew

-- AQUI PEGO O STATUS DO PRIMEIRO CURSOR
SET @FETCH_PRIMEIRO_CURSOR = @@FETCH_STATUS


WHILE (@@FETCH_PRIMEIRO_CURSOR=0)
 BEGIN 

    DECLARE SERVIDOR_CURSOR CURSOR FOR SELECT codigo,telefone FROM servidor , registoOperacoes WHERE servidor.codigo=@codigoNew
    OPEN SERVIDOR_CURSOR
    FETCH NEXT FROM SERVIDOR_CURSOR INTO  @codigo,@telefone

    -- AQUI PEGO O STATUS DO SEGUNDO CURSOR
    SET @FETCH_SEGUNDO_CURSOR = @@FETCH_STATUS

    WHILE (@@FETCH_SEGUNDO_CURSOR=0)
    BEGIN 
        IF @timestampOld<@timestampNew
        print N'Código: '+CAST(@codigo AS NVARCHAR(10))+' Telefone: '+CAST(@telefone AS NVARCHAR(15));
        UPDATE servidor 
        SET codigo=@codigo,telefone=@telefone
        WHERE codigo=@codigo

        FETCH NEXT FROM SERVIDOR_CURSOR INTO  @codigo,@telefone
        -- AQUI PEGO O STATUS DO SEGUNDO CURSOR
        SET @FETCH_SEGUNDO_CURSOR = @@FETCH_STATUS
    END

    CLOSE SERVIDOR_CURSOR
    DEALLOCATE SERVIDOR_CURSOR 

    FETCH NEXT FROM CONFLITO_CURSOR INTO @sequencia,@codigoOld,@telefoneOld,@timestampOld,@vetorOld,@codigoNew,@telefoneNew,@timestampNew,@vetorNew
    -- AQUI PEGO O STATUS DO PRIMEIRO CURSOR
    SET @FETCH_PRIMEIRO_CURSOR = @@FETCH_STATUS
END   
  • I did as your guidance did not work

  • Okay, but what didn’t work? There was some mistake?

  • No error. Runs however, does not update or print

  • Ran normally however no printed nor updated server table.

  • I guess after every fetch it would be interesting to print the values of all variables to see if you are getting the correct values. In your code, it will only be printed if the IF @timestampOld<@timestampNew be true

Browser other questions tagged

You are not signed in. Login or sign up in order to post.