Actualización muy lenta

27/10/2004 - 10:51 por Javi | Informe spam
Siguiendo los consejos del grupo he realizado un proceso almacenado para
actualizar una tabla de más de 33 millones de registros, pero me funciona
muy lento, para actualizar 50.000 registros tarda dos horas y esto al
cliente le parece excesivo, así que os mando el código para ver si alguien
me ayuda a optimizarlo.
Este código es mi primera experiencia con cursores y procesos almacenados,
así que estoy convencido de que no debe ser la mejor forma de usarlos, así
que cualquier consejo será muy bien recibido.

Aquí va el código:

IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'get_ID_TP_TDA' AND type = 'P')
DROP PROCEDURE get_ID_TP_TDA

GO

CREATE PROCEDURE get_ID_TP_TDA
@TpTda varchar(1) OUTPUT

AS
DECLARE @Empr decimal
DECLARE @Tda decimal
DECLARE @Del decimal

SELECT TOP 1
@Empr = ID_EMPR,
@Tda = ID_TDA,
@Del = ID_DEL
FROM
Ventas
WHERE
ID_TP_TDA IS NULL

SELECT
@TpTda = ID_TP_TDA
FROM
Tiendas
WHERE
ID_EMPR = @Empr AND
ID_TDA = @Tda AND
ID_DEL = @Del
RETURN

GO

DECLARE MiCursor CURSOR
FOR
SELECT
ID_TP_TDA
FROM
Ventas
WHERE
ID_TP_TDA IS NULL
FOR UPDATE OF ID_TP_TDA

OPEN MiCursor
DECLARE @NUMERO_DE_REGISTROS_ACTUALIZADOS int
SET @NUMERO_DE_REGISTROS_ACTUALIZADOS = 0

DECLARE @HORA_INICIAL datetime
SET @HORA_INICIAL = GETDATE()



WHILE (@@FETCH_STATUS = 0 AND @NUMERO_DE_REGISTROS_ACTUALIZADOS < 50000) /*
< Numero de registros máximo a actualizar */

BEGIN
DECLARE @TipoTienda varchar(1)
DECLARE @TipoTiendaNULL varchar(1)

EXECUTE get_ID_TP_TDA
@TpTda = @TipoTienda OUTPUT

FETCH NEXT FROM MiCursor INTO @TipoTiendaNULL /* Evita que el resultado
se muestre en pantalla */

UPDATE
Ventas
SET
Ventas.ID_TP_TDA = @TipoTienda
FROM
Ventas
WHERE CURRENT OF MiCursor

SET @NUMERO_DE_REGISTROS_ACTUALIZADOS = @NUMERO_DE_REGISTROS_ACTUALIZADOS +
1
END

DECLARE @HORA_FINAL datetime
SET @HORA_FINAL = GETDATE()

SELECT @NUMERO_DE_REGISTROS_ACTUALIZADOS AS 'Número de registros',
@HORA_INICIAL as 'Hora de comienzo', @HORA_FINAL as 'Hora de finalización'

CLOSE MiCursor

DEALLOCATE MiCursor


Muchas gracias a todos

Javi

Preguntas similare

Leer las respuestas

#1 Liliana Sorrentino
27/10/2004 - 13:50 | Informe spam
Hola Javi,
No sé si el tope de 50.000 filas es obligatorio, pero sin ese control,
podrías probar de esta manera.

UPDATE
V1
SET
V1.ID_TP_TDA = V2.ID_TP_TDA
FROM #Ventas V1
INNER JOIN #Ventas V2
ON V1.ID_EMPR = V2.ID_EMPR AND V1.ID_TDA = V2.ID_TDA AND V1.ID_DEL V2.ID_DEL
WHERE
V1.ID_TP_TDA IS NULL AND V2.ID_TP_TDA IS NOT NULL

Saludos, Liliana.

"Javi" escribió en el mensaje
news:#
Siguiendo los consejos del grupo he realizado un proceso almacenado para
actualizar una tabla de más de 33 millones de registros, pero me funciona
muy lento, para actualizar 50.000 registros tarda dos horas y esto al
cliente le parece excesivo, así que os mando el código para ver si alguien
me ayuda a optimizarlo.
Este código es mi primera experiencia con cursores y procesos almacenados,
así que estoy convencido de que no debe ser la mejor forma de usarlos, así
que cualquier consejo será muy bien recibido.

Aquí va el código:

IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'get_ID_TP_TDA' AND type = 'P')
DROP PROCEDURE get_ID_TP_TDA

GO

CREATE PROCEDURE get_ID_TP_TDA
@TpTda varchar(1) OUTPUT

AS
DECLARE @Empr decimal
DECLARE @Tda decimal
DECLARE @Del decimal

SELECT TOP 1
@Empr = ID_EMPR,
@Tda = ID_TDA,
@Del = ID_DEL
FROM
Ventas
WHERE
ID_TP_TDA IS NULL

SELECT
@TpTda = ID_TP_TDA
FROM
Tiendas
WHERE
ID_EMPR = @Empr AND
ID_TDA = @Tda AND
ID_DEL = @Del
RETURN

GO

DECLARE MiCursor CURSOR
FOR
SELECT
ID_TP_TDA
FROM
Ventas
WHERE
ID_TP_TDA IS NULL
FOR UPDATE OF ID_TP_TDA

OPEN MiCursor
DECLARE @NUMERO_DE_REGISTROS_ACTUALIZADOS int
SET @NUMERO_DE_REGISTROS_ACTUALIZADOS = 0

DECLARE @HORA_INICIAL datetime
SET @HORA_INICIAL = GETDATE()



WHILE (@@FETCH_STATUS = 0 AND @NUMERO_DE_REGISTROS_ACTUALIZADOS < 50000)


/*
< Numero de registros máximo a actualizar */

BEGIN
DECLARE @TipoTienda varchar(1)
DECLARE @TipoTiendaNULL varchar(1)

EXECUTE get_ID_TP_TDA
@TpTda = @TipoTienda OUTPUT

FETCH NEXT FROM MiCursor INTO @TipoTiendaNULL /* Evita que el


resultado
se muestre en pantalla */

UPDATE
Ventas
SET
Ventas.ID_TP_TDA = @TipoTienda
FROM
Ventas
WHERE CURRENT OF MiCursor

SET @NUMERO_DE_REGISTROS_ACTUALIZADOS = @NUMERO_DE_REGISTROS_ACTUALIZADOS


+
1
END

DECLARE @HORA_FINAL datetime
SET @HORA_FINAL = GETDATE()

SELECT @NUMERO_DE_REGISTROS_ACTUALIZADOS AS 'Número de registros',
@HORA_INICIAL as 'Hora de comienzo', @HORA_FINAL as 'Hora de finalización'

CLOSE MiCursor

DEALLOCATE MiCursor


Muchas gracias a todos

Javi


Respuesta Responder a este mensaje
#2 Javi
27/10/2004 - 17:00 | Informe spam
Hola Liliana.

Una consulta así es lo primero que pensé, pero duraba tanto que bloqueaba
otros procesos, de ahí el poner el límite de filas, para que llegado un
momento pare la actualización y desbloquee otros procesos que quieren
escribir sobre la misma tabla de Ventas.

Un saludo
Javi

"Liliana Sorrentino" escribió en el mensaje
news:
Hola Javi,
No sé si el tope de 50.000 filas es obligatorio, pero sin ese control,
podrías probar de esta manera.

UPDATE
V1
SET
V1.ID_TP_TDA = V2.ID_TP_TDA
FROM #Ventas V1
INNER JOIN #Ventas V2
ON V1.ID_EMPR = V2.ID_EMPR AND V1.ID_TDA = V2.ID_TDA AND V1.ID_DEL > V2.ID_DEL
WHERE
V1.ID_TP_TDA IS NULL AND V2.ID_TP_TDA IS NOT NULL

Saludos, Liliana.

"Javi" escribió en el mensaje
news:#
Siguiendo los consejos del grupo he realizado un proceso almacenado para
actualizar una tabla de más de 33 millones de registros, pero me funciona
muy lento, para actualizar 50.000 registros tarda dos horas y esto al
cliente le parece excesivo, así que os mando el código para ver si
alguien
me ayuda a optimizarlo.
Este código es mi primera experiencia con cursores y procesos
almacenados,
así que estoy convencido de que no debe ser la mejor forma de usarlos,
así
que cualquier consejo será muy bien recibido.

Aquí va el código:

IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'get_ID_TP_TDA' AND type = 'P')
DROP PROCEDURE get_ID_TP_TDA

GO

CREATE PROCEDURE get_ID_TP_TDA
@TpTda varchar(1) OUTPUT

AS
DECLARE @Empr decimal
DECLARE @Tda decimal
DECLARE @Del decimal

SELECT TOP 1
@Empr = ID_EMPR,
@Tda = ID_TDA,
@Del = ID_DEL
FROM
Ventas
WHERE
ID_TP_TDA IS NULL

SELECT
@TpTda = ID_TP_TDA
FROM
Tiendas
WHERE
ID_EMPR = @Empr AND
ID_TDA = @Tda AND
ID_DEL = @Del
RETURN

GO

DECLARE MiCursor CURSOR
FOR
SELECT
ID_TP_TDA
FROM
Ventas
WHERE
ID_TP_TDA IS NULL
FOR UPDATE OF ID_TP_TDA

OPEN MiCursor
DECLARE @NUMERO_DE_REGISTROS_ACTUALIZADOS int
SET @NUMERO_DE_REGISTROS_ACTUALIZADOS = 0

DECLARE @HORA_INICIAL datetime
SET @HORA_INICIAL = GETDATE()



WHILE (@@FETCH_STATUS = 0 AND @NUMERO_DE_REGISTROS_ACTUALIZADOS < 50000)


/*
< Numero de registros máximo a actualizar */

BEGIN
DECLARE @TipoTienda varchar(1)
DECLARE @TipoTiendaNULL varchar(1)

EXECUTE get_ID_TP_TDA
@TpTda = @TipoTienda OUTPUT

FETCH NEXT FROM MiCursor INTO @TipoTiendaNULL /* Evita que el


resultado
se muestre en pantalla */

UPDATE
Ventas
SET
Ventas.ID_TP_TDA = @TipoTienda
FROM
Ventas
WHERE CURRENT OF MiCursor

SET @NUMERO_DE_REGISTROS_ACTUALIZADOS =
@NUMERO_DE_REGISTROS_ACTUALIZADOS


+
1
END

DECLARE @HORA_FINAL datetime
SET @HORA_FINAL = GETDATE()

SELECT @NUMERO_DE_REGISTROS_ACTUALIZADOS AS 'Número de registros',
@HORA_INICIAL as 'Hora de comienzo', @HORA_FINAL as 'Hora de
finalización'

CLOSE MiCursor

DEALLOCATE MiCursor


Muchas gracias a todos

Javi






Respuesta Responder a este mensaje
#3 Liliana Sorrentino
27/10/2004 - 17:26 | Informe spam
Bueno, podrías usar un
SET ROWCOUNT 3
GO
UPDATE.
GO
SET ROWCOUNT 0
GO

Pero tengo una duda. ¿Podés tener para la misma clave (ID_EMPR, ID_TDA,
ID_DEL) distintos ID_TP_TDA?

"Javi" escribió en el mensaje
news:eZK#
Hola Liliana.

Una consulta así es lo primero que pensé, pero duraba tanto que bloqueaba
otros procesos, de ahí el poner el límite de filas, para que llegado un
momento pare la actualización y desbloquee otros procesos que quieren
escribir sobre la misma tabla de Ventas.

Un saludo
Javi

"Liliana Sorrentino" escribió en el


mensaje
news:
> Hola Javi,
> No sé si el tope de 50.000 filas es obligatorio, pero sin ese control,
> podrías probar de esta manera.
>
> UPDATE
> V1
> SET
> V1.ID_TP_TDA = V2.ID_TP_TDA
> FROM #Ventas V1
> INNER JOIN #Ventas V2
> ON V1.ID_EMPR = V2.ID_EMPR AND V1.ID_TDA = V2.ID_TDA AND V1.ID_DEL > > V2.ID_DEL
> WHERE
> V1.ID_TP_TDA IS NULL AND V2.ID_TP_TDA IS NOT NULL
>
> Saludos, Liliana.
>
> "Javi" escribió en el mensaje
> news:#
>> Siguiendo los consejos del grupo he realizado un proceso almacenado


para
>> actualizar una tabla de más de 33 millones de registros, pero me


funciona
>> muy lento, para actualizar 50.000 registros tarda dos horas y esto al
>> cliente le parece excesivo, así que os mando el código para ver si
>> alguien
>> me ayuda a optimizarlo.
>> Este código es mi primera experiencia con cursores y procesos
>> almacenados,
>> así que estoy convencido de que no debe ser la mejor forma de usarlos,
>> así
>> que cualquier consejo será muy bien recibido.
>>
>> Aquí va el código:
>>
>> IF EXISTS (SELECT name FROM sysobjects
>> WHERE name = 'get_ID_TP_TDA' AND type = 'P')
>> DROP PROCEDURE get_ID_TP_TDA
>>
>> GO
>>
>> CREATE PROCEDURE get_ID_TP_TDA
>> @TpTda varchar(1) OUTPUT
>>
>> AS
>> DECLARE @Empr decimal
>> DECLARE @Tda decimal
>> DECLARE @Del decimal
>>
>> SELECT TOP 1
>> @Empr = ID_EMPR,
>> @Tda = ID_TDA,
>> @Del = ID_DEL
>> FROM
>> Ventas
>> WHERE
>> ID_TP_TDA IS NULL
>>
>> SELECT
>> @TpTda = ID_TP_TDA
>> FROM
>> Tiendas
>> WHERE
>> ID_EMPR = @Empr AND
>> ID_TDA = @Tda AND
>> ID_DEL = @Del
>> RETURN
>>
>> GO
>>
>> DECLARE MiCursor CURSOR
>> FOR
>> SELECT
>> ID_TP_TDA
>> FROM
>> Ventas
>> WHERE
>> ID_TP_TDA IS NULL
>> FOR UPDATE OF ID_TP_TDA
>>
>> OPEN MiCursor
>> DECLARE @NUMERO_DE_REGISTROS_ACTUALIZADOS int
>> SET @NUMERO_DE_REGISTROS_ACTUALIZADOS = 0
>>
>> DECLARE @HORA_INICIAL datetime
>> SET @HORA_INICIAL = GETDATE()
>>
>>
>>
>> WHILE (@@FETCH_STATUS = 0 AND @NUMERO_DE_REGISTROS_ACTUALIZADOS <


50000)
> /*
>> < Numero de registros máximo a actualizar */
>>
>> BEGIN
>> DECLARE @TipoTienda varchar(1)
>> DECLARE @TipoTiendaNULL varchar(1)
>>
>> EXECUTE get_ID_TP_TDA
>> @TpTda = @TipoTienda OUTPUT
>>
>> FETCH NEXT FROM MiCursor INTO @TipoTiendaNULL /* Evita que el
> resultado
>> se muestre en pantalla */
>>
>> UPDATE
>> Ventas
>> SET
>> Ventas.ID_TP_TDA = @TipoTienda
>> FROM
>> Ventas
>> WHERE CURRENT OF MiCursor
>>
>> SET @NUMERO_DE_REGISTROS_ACTUALIZADOS > >> @NUMERO_DE_REGISTROS_ACTUALIZADOS
> +
>> 1
>> END
>>
>> DECLARE @HORA_FINAL datetime
>> SET @HORA_FINAL = GETDATE()
>>
>> SELECT @NUMERO_DE_REGISTROS_ACTUALIZADOS AS 'Número de registros',
>> @HORA_INICIAL as 'Hora de comienzo', @HORA_FINAL as 'Hora de
>> finalización'
>>
>> CLOSE MiCursor
>>
>> DEALLOCATE MiCursor
>>
>>
>> Muchas gracias a todos
>>
>> Javi
>>
>>
>
>


Respuesta Responder a este mensaje
#4 Javi
27/10/2004 - 18:24 | Informe spam
Perdona mi ignorancia, pero para que sirve eso del ROWCOUNT?

En la tabla tiendas existe un solo ID_TP_TDA por cada clave ID_EMPR, ID_TDA
e ID_DEL.


"Liliana Sorrentino" escribió en el mensaje
news:
Bueno, podrías usar un
SET ROWCOUNT 3
GO
UPDATE.
GO
SET ROWCOUNT 0
GO

Pero tengo una duda. ¿Podés tener para la misma clave (ID_EMPR, ID_TDA,
ID_DEL) distintos ID_TP_TDA?

"Javi" escribió en el mensaje
news:eZK#
Hola Liliana.

Una consulta así es lo primero que pensé, pero duraba tanto que bloqueaba
otros procesos, de ahí el poner el límite de filas, para que llegado un
momento pare la actualización y desbloquee otros procesos que quieren
escribir sobre la misma tabla de Ventas.

Un saludo
Javi

"Liliana Sorrentino" escribió en el


mensaje
news:
> Hola Javi,
> No sé si el tope de 50.000 filas es obligatorio, pero sin ese control,
> podrías probar de esta manera.
>
> UPDATE
> V1
> SET
> V1.ID_TP_TDA = V2.ID_TP_TDA
> FROM #Ventas V1
> INNER JOIN #Ventas V2
> ON V1.ID_EMPR = V2.ID_EMPR AND V1.ID_TDA = V2.ID_TDA AND V1.ID_DEL >> > V2.ID_DEL
> WHERE
> V1.ID_TP_TDA IS NULL AND V2.ID_TP_TDA IS NOT NULL
>
> Saludos, Liliana.
>
> "Javi" escribió en el mensaje
> news:#
>> Siguiendo los consejos del grupo he realizado un proceso almacenado


para
>> actualizar una tabla de más de 33 millones de registros, pero me


funciona
>> muy lento, para actualizar 50.000 registros tarda dos horas y esto al
>> cliente le parece excesivo, así que os mando el código para ver si
>> alguien
>> me ayuda a optimizarlo.
>> Este código es mi primera experiencia con cursores y procesos
>> almacenados,
>> así que estoy convencido de que no debe ser la mejor forma de usarlos,
>> así
>> que cualquier consejo será muy bien recibido.
>>
>> Aquí va el código:
>>
>> IF EXISTS (SELECT name FROM sysobjects
>> WHERE name = 'get_ID_TP_TDA' AND type = 'P')
>> DROP PROCEDURE get_ID_TP_TDA
>>
>> GO
>>
>> CREATE PROCEDURE get_ID_TP_TDA
>> @TpTda varchar(1) OUTPUT
>>
>> AS
>> DECLARE @Empr decimal
>> DECLARE @Tda decimal
>> DECLARE @Del decimal
>>
>> SELECT TOP 1
>> @Empr = ID_EMPR,
>> @Tda = ID_TDA,
>> @Del = ID_DEL
>> FROM
>> Ventas
>> WHERE
>> ID_TP_TDA IS NULL
>>
>> SELECT
>> @TpTda = ID_TP_TDA
>> FROM
>> Tiendas
>> WHERE
>> ID_EMPR = @Empr AND
>> ID_TDA = @Tda AND
>> ID_DEL = @Del
>> RETURN
>>
>> GO
>>
>> DECLARE MiCursor CURSOR
>> FOR
>> SELECT
>> ID_TP_TDA
>> FROM
>> Ventas
>> WHERE
>> ID_TP_TDA IS NULL
>> FOR UPDATE OF ID_TP_TDA
>>
>> OPEN MiCursor
>> DECLARE @NUMERO_DE_REGISTROS_ACTUALIZADOS int
>> SET @NUMERO_DE_REGISTROS_ACTUALIZADOS = 0
>>
>> DECLARE @HORA_INICIAL datetime
>> SET @HORA_INICIAL = GETDATE()
>>
>>
>>
>> WHILE (@@FETCH_STATUS = 0 AND @NUMERO_DE_REGISTROS_ACTUALIZADOS <


50000)
> /*
>> < Numero de registros máximo a actualizar */
>>
>> BEGIN
>> DECLARE @TipoTienda varchar(1)
>> DECLARE @TipoTiendaNULL varchar(1)
>>
>> EXECUTE get_ID_TP_TDA
>> @TpTda = @TipoTienda OUTPUT
>>
>> FETCH NEXT FROM MiCursor INTO @TipoTiendaNULL /* Evita que el
> resultado
>> se muestre en pantalla */
>>
>> UPDATE
>> Ventas
>> SET
>> Ventas.ID_TP_TDA = @TipoTienda
>> FROM
>> Ventas
>> WHERE CURRENT OF MiCursor
>>
>> SET @NUMERO_DE_REGISTROS_ACTUALIZADOS >> >> @NUMERO_DE_REGISTROS_ACTUALIZADOS
> +
>> 1
>> END
>>
>> DECLARE @HORA_FINAL datetime
>> SET @HORA_FINAL = GETDATE()
>>
>> SELECT @NUMERO_DE_REGISTROS_ACTUALIZADOS AS 'Número de registros',
>> @HORA_INICIAL as 'Hora de comienzo', @HORA_FINAL as 'Hora de
>> finalización'
>>
>> CLOSE MiCursor
>>
>> DEALLOCATE MiCursor
>>
>>
>> Muchas gracias a todos
>>
>> Javi
>>
>>
>
>






Respuesta Responder a este mensaje
#5 Liliana Sorrentino
27/10/2004 - 19:00 | Informe spam
El ROWCOUNT n, indica la cantidad de filas afectadas por las instrucciones
que están a continuación.
En este caso el UPDATE dejará de trabajar cuando llegue a los 50.000.
A continuación, tenés que acordarte de setearlo a 0, que es volverlo a la
normalidad.

En cuando a que haya un solo ID_TP_TDA por cada clave, entonces se podría
optimizar tomando solo una fila por cada clave que tenga datos, de esta
manera:

SET ROWCOUNT 50000
GO

UPDATE
V1
SET
V1.ID_TP_TDA = V2.ID_TP_TDA
FROM #Ventas V1
INNER JOIN (SELECT ID_EMPR, ID_TDA, ID_DEL, ID_TP_TDA = MIN(ID_TP_TDA)
FROM #Ventas
WHERE ID_TP_TDA IS NOT NULL
GROUP BY ID_EMPR, ID_TDA, ID_DEL) V2
ON V1.ID_EMPR = V2.ID_EMPR AND V1.ID_TDA = V2.ID_TDA AND V1.ID_DEL V2.ID_DEL and V1.ID_TP_TDA IS NULL
GO

SET ROWCOUNT 0
GO

Liliana.
"Javi" escribió en el mensaje
news:#
Perdona mi ignorancia, pero para que sirve eso del ROWCOUNT?

En la tabla tiendas existe un solo ID_TP_TDA por cada clave ID_EMPR,


ID_TDA
e ID_DEL.


"Liliana Sorrentino" escribió en el


mensaje
news:
> Bueno, podrías usar un
> SET ROWCOUNT 3
> GO
> UPDATE.
> GO
> SET ROWCOUNT 0
> GO
>
> Pero tengo una duda. ¿Podés tener para la misma clave (ID_EMPR, ID_TDA,
> ID_DEL) distintos ID_TP_TDA?
>
> "Javi" escribió en el mensaje
> news:eZK#
>> Hola Liliana.
>>
>> Una consulta así es lo primero que pensé, pero duraba tanto que


bloqueaba
>> otros procesos, de ahí el poner el límite de filas, para que llegado un
>> momento pare la actualización y desbloquee otros procesos que quieren
>> escribir sobre la misma tabla de Ventas.
>>
>> Un saludo
>> Javi
>>
>> "Liliana Sorrentino" escribió en el
> mensaje
>> news:
>> > Hola Javi,
>> > No sé si el tope de 50.000 filas es obligatorio, pero sin ese


control,
>> > podrías probar de esta manera.
>> >
>> > UPDATE
>> > V1
>> > SET
>> > V1.ID_TP_TDA = V2.ID_TP_TDA
>> > FROM #Ventas V1
>> > INNER JOIN #Ventas V2
>> > ON V1.ID_EMPR = V2.ID_EMPR AND V1.ID_TDA = V2.ID_TDA AND V1.ID_DEL > >> > V2.ID_DEL
>> > WHERE
>> > V1.ID_TP_TDA IS NULL AND V2.ID_TP_TDA IS NOT NULL
>> >
>> > Saludos, Liliana.
>> >
>> > "Javi" escribió en el mensaje
>> > news:#
>> >> Siguiendo los consejos del grupo he realizado un proceso almacenado
> para
>> >> actualizar una tabla de más de 33 millones de registros, pero me
> funciona
>> >> muy lento, para actualizar 50.000 registros tarda dos horas y esto


al
>> >> cliente le parece excesivo, así que os mando el código para ver si
>> >> alguien
>> >> me ayuda a optimizarlo.
>> >> Este código es mi primera experiencia con cursores y procesos
>> >> almacenados,
>> >> así que estoy convencido de que no debe ser la mejor forma de


usarlos,
>> >> así
>> >> que cualquier consejo será muy bien recibido.
>> >>
>> >> Aquí va el código:
>> >>
>> >> IF EXISTS (SELECT name FROM sysobjects
>> >> WHERE name = 'get_ID_TP_TDA' AND type = 'P')
>> >> DROP PROCEDURE get_ID_TP_TDA
>> >>
>> >> GO
>> >>
>> >> CREATE PROCEDURE get_ID_TP_TDA
>> >> @TpTda varchar(1) OUTPUT
>> >>
>> >> AS
>> >> DECLARE @Empr decimal
>> >> DECLARE @Tda decimal
>> >> DECLARE @Del decimal
>> >>
>> >> SELECT TOP 1
>> >> @Empr = ID_EMPR,
>> >> @Tda = ID_TDA,
>> >> @Del = ID_DEL
>> >> FROM
>> >> Ventas
>> >> WHERE
>> >> ID_TP_TDA IS NULL
>> >>
>> >> SELECT
>> >> @TpTda = ID_TP_TDA
>> >> FROM
>> >> Tiendas
>> >> WHERE
>> >> ID_EMPR = @Empr AND
>> >> ID_TDA = @Tda AND
>> >> ID_DEL = @Del
>> >> RETURN
>> >>
>> >> GO
>> >>
>> >> DECLARE MiCursor CURSOR
>> >> FOR
>> >> SELECT
>> >> ID_TP_TDA
>> >> FROM
>> >> Ventas
>> >> WHERE
>> >> ID_TP_TDA IS NULL
>> >> FOR UPDATE OF ID_TP_TDA
>> >>
>> >> OPEN MiCursor
>> >> DECLARE @NUMERO_DE_REGISTROS_ACTUALIZADOS int
>> >> SET @NUMERO_DE_REGISTROS_ACTUALIZADOS = 0
>> >>
>> >> DECLARE @HORA_INICIAL datetime
>> >> SET @HORA_INICIAL = GETDATE()
>> >>
>> >>
>> >>
>> >> WHILE (@@FETCH_STATUS = 0 AND @NUMERO_DE_REGISTROS_ACTUALIZADOS <
> 50000)
>> > /*
>> >> < Numero de registros máximo a actualizar */
>> >>
>> >> BEGIN
>> >> DECLARE @TipoTienda varchar(1)
>> >> DECLARE @TipoTiendaNULL varchar(1)
>> >>
>> >> EXECUTE get_ID_TP_TDA
>> >> @TpTda = @TipoTienda OUTPUT
>> >>
>> >> FETCH NEXT FROM MiCursor INTO @TipoTiendaNULL /* Evita que el
>> > resultado
>> >> se muestre en pantalla */
>> >>
>> >> UPDATE
>> >> Ventas
>> >> SET
>> >> Ventas.ID_TP_TDA = @TipoTienda
>> >> FROM
>> >> Ventas
>> >> WHERE CURRENT OF MiCursor
>> >>
>> >> SET @NUMERO_DE_REGISTROS_ACTUALIZADOS > >> >> @NUMERO_DE_REGISTROS_ACTUALIZADOS
>> > +
>> >> 1
>> >> END
>> >>
>> >> DECLARE @HORA_FINAL datetime
>> >> SET @HORA_FINAL = GETDATE()
>> >>
>> >> SELECT @NUMERO_DE_REGISTROS_ACTUALIZADOS AS 'Número de registros',
>> >> @HORA_INICIAL as 'Hora de comienzo', @HORA_FINAL as 'Hora de
>> >> finalización'
>> >>
>> >> CLOSE MiCursor
>> >>
>> >> DEALLOCATE MiCursor
>> >>
>> >>
>> >> Muchas gracias a todos
>> >>
>> >> Javi
>> >>
>> >>
>> >
>> >
>>
>>
>
>


email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida