lunes, 15 de julio de 2013

Cursores en SQL Server

Aquí se muestra cómo crear un cursor que tome de una Base de Datos una gran cantidad de registros para tratarlos uno a uno de forma rápida y automática  sin necesidad de tener que ejecutar una instrucción por cada registro.

En primer lugar declaramos la transacción y creamos las variables correspondientes:
begin transaction
    -- declaramos las variables
      DECLARE @intcodigorecepcion as integer
   DECLARE @strnumerodoc as nvarchar(13)
   DECLARE @datFechaPago as datetime
   DECLARE @i INTEGER --Contador
  

Declaración del cursor.
declare facturas INSENSITIVE cursor for

Select de extracción los datos, los campos que extrae y su orden son importantes por que son los que posteriormente se asignarán a las variables.

select datFechaPago,strNumDocDC, intCodRecepcion from dbo.tbVidaContableExpediente where datFechapago is not NULL and strNumDocDC in (select strnumdocucon from dbo2.tbFacturas where strNumeroFactura like '2012%' and datFechaPago is NULL and srnumdocucon is not NULL)   
      
Apertura del cursor
open facturas

Comienzo del blucle
SELECT @i = @@CURSOR_ROWS

-- Avanzamos un registro y cargamos en las variables los valores encontrados en el primer registro
    
Se mete cada valor de la select anterior en su campo correspondiente teniendo en cuenta su orden. @strIntCodigorecepcion se le asigna el primer campo de la select, a @strnumerodoc se le asigna el segundo campo de la select, etc.

fetch next from facturas into @datFechaPago, @strnumerodoc, @intcodigorecepcion
            WHILE @i > 0
            BEGIN
                  SELECT @i = @i - 1

Condición para la modificación (opcional) en este caso sólo modifica el registro si el numero de documento obtenido existe en una tabla concreta.

IF (select count(*) from dbo.tbdocumentocontable where strnumerodocumento = @strnumerodoc) > 0

Actualización, aqui es donde finalmente modifica cada registro que cumpla las condiciones con los valores previamente obtenidos de la select

UPDATE dbo2.tbfacturas set datFechaPago=@datFechaPago where intnfacturadocumenta=@intcodigorecepcion and strnumDocuCon = @strnumerodoc    

También se permitre sacar por pantalla información relevante
print @strnumerodoc 
                                               
Avanzamos al siguiente registro
fetch next from facturas into @datFechaPago, @strnumerodoc, 
@intcodigorecepcion

END

cerramos el cursor
close facturas
deallocate facturas

Cerramos la transacción
commit  Transaction


El Cursor completo quedaría así


begin transaction
    -- declaramos las variables
      DECLARE @intcodigorecepcion as integer
      DECLARE @strnumerodoc as nvarchar(13)
      DECLARE @datFechaPago as datetime
      DECLARE @i INTEGER 
    
      declare facturas INSENSITIVE cursor for
          
select datFechaPago,strNumDocDC, intCodRecepcion from dbo.tbVidaContableExpediente where datFechapago is not NULL and strNumDocDC in (select strnumdocucon from dbo2.tbFacturas where strNumeroFactura like '2012%' and datFechaPago is NULL and srnumdocucon is not NULL)      
            open facturas
            SELECT @i = @@CURSOR_ROWS
        -- Avanzamos un registro y cargamos en las variables los valores encontrados en el primer registro
      fetch next from facturas into @datFechaPago, @strnumerodoc, @intcodigorecepcion
            WHILE @i > 0
            BEGIN
                  SELECT @i = @i - 1
UPDATE dbo2.tbfacturas set datFechaPago=@datFechaPago where intnfacturadocumenta=@intcodigorecepcion and strnumDocuCon = @strnumerodoc                                               
            -- Avanzamos otro registro
fetch next from facturas into @datFechaPago, @strnumerodoc,@intcodigorecepcion
            END
-- cerramos el cursor
close facturas
deallocate facturas
commit  Transaction





No hay comentarios:

Publicar un comentario