En este artículo se muestra como cambiar el uso de un CURSOR por una sentencia WHILE, la cuál nos mejorara el performance en un 75%.

Desde mi punto de vista lo último que se debe de hacer en el diseño de una aplicación es hacer uso de los cursores, ya que consumen muchos recursos y son muy lentos. Así que debemos de tomarlos como la última alternativa en un desarrollo.

Supongamos que tenemos el siguiente cursor

DECLARE @item_category_id INT
DECLARE @order_id INT
DECLARE @purchase_order_id INT

DECLARE item_cursor CURSOR FAST_FORWARD FOR

SELECT
it.item_category_id
,ord.order_id
FROM dbo.item_categories it

INNER JOIN dbo.orders ord
ON ord.item_category_id = it.item_category_id

WHERE ord.order_date >= '1-sep-05'
and it.isSuspended != 1

OPEN item_cursor

FETCH NEXT FROM item_cursor INTO
@item_category_id
,@order_id

WHILE @@FETCH_STATUS = 0
BEGIN
EXEC dbo.usp_generate_purchase_order @item_category_id, @order_id, @purchase_order_id OUTPUT

/*
Codigo extra propio de nuestra aplicación
*/

FETCH NEXT FROM item_cursor INTO
@item-category_id
,@order_id
END

Ahora este es el codigo sin la necesidad de hacer uso de cursores y que nos da el mismo resultado usando un loop While.

--Declarando Variables
DECLARE @item_category_id INT
DECLARE @order_id INT
DECLARE @purchase_order_id INT

--Declarando tabla
DECLARE @item_table TABLE (primary_key INT IDENTITY(1,1) NOT NULL, --THE IDENTITY STATEMENT IS IMPORTANT!
item_category_id INT,
order_id INT
)

--Insertar los registros en nuestra tabla tal y como se seleccionaban en el Cursor
INSERT INTO @item_table
SELECT
it.item_category_id
,ord.order_id
FROM dbo.item_categories it

INNER JOIN dbo.orders ord
ON ord.item_category_id = it.item_category_id

WHERE ord.order_date >= '1-sep-05'
and it.isSuspended != 1

DECLARE @item_category_counter INT
DECLARE @loop_counter INT

SET @loop_counter = ISNULL((SELECT COUNT(*) FROM @item_table),0) -- Hacer el conteo de registros de nuestra tabla

SET @item_category_counter = 1

WHILE @loop_counter > 0 AND @item_category_counter <= @loop_counter
BEGIN
SELECT @item_category_id = item_category_id
,@order_id = order_id
FROM @item_table
WHERE primary_key = @item_category_counter

--Ahora pasar el item-category_id y order_id al store procedure
EXEC dbo.usp_generate_purchase_order @item_category_id, @order_id, @purchase_order_id OUTPUT

/*
Codigo extra de nuestra aplicación
*/

SET @item_category_counter = @item_category_counter + 1
END

Este cambio nos mejora el performance en un 75%, a comparación de un CURSO. Existen algunos casos que no son muy comunes, en el cuál es preferible hacer uso de un cursor, pero en un 99% solo te va a alentar tu aplicación, así que evita hacer uso de ellos.

You are not authorised to post comments.

Comments powered by CComment

DBASupport - Foro

Mirroring con estados disconnected
Hola, el día de hoy después de reiniciar mi servidor de destino a donde realizo el mirroring ya no pude replicar más, el error que muestra es que...

Se me duplica el mensaje en /etc/motd
  • Topic started by agamez
  • in General
  • 3 years ago.
  • 3 years ago.
  • 2 replies
Buen día, alguien tiene idea porque después de actualizar a fedora 28 se me esta duplicando la salida de mi /etc/motd?

Cómo puedo filtrar un mensaje en el log messages
Buenos días, estoy recibiendo en mi log de errores muchos mensajes de cron, ya que tengo varios crones configurados en mi server. Existe alguna...

Cómo validar la hora de ejecución de un proceso
Hola, estoy tratando de validar que un proceso sólo pueda ser ejecutado dentro de un periodo de tiempo, en este caso entre las 7:00 AM y las 7:00...

Estadisticas en la base de datos
Buenos días, estoy teniendo problemas de performance en mis queries y quisiera saber como puedo validar que mis tablas tienen las estadisticas...
URGE AYUDA
  • Topic started by
  • in General
  • 15 years ago.
  • 15 years ago.
  • 30 replies
HOLA ESPERO ME PUEDAN AYUDAR. TEN GO UNA TABLA CON una estructura similar a la siguiente: id_mov cargo subtotal total...

Duada de Memoria de SQL Server 2005
  • Topic started by Erzengel
  • in General
  • 11 years ago.
  • 11 years ago.
  • 30 replies
Buen Día Recurro nuevamente a su sabiduría. Quiero saber el porque tiene un tope SQL Serever de 2GB en Windows server 2003 de 32 bit y si alguien...

SqlDateTime overflow
  • Topic started by
  • in General
  • 15 years ago.
  • 15 years ago.
  • 11 replies
Alguno de ustedes ha tenido este problema: SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.' Les...

problemas para iniciar el agente sql
  • Topic started by acgch
  • in General
  • 14 years ago.
  • 14 years ago.
  • 11 replies
Recientemente para asegurar el sql server 2005, cree una cuenta sql con derechos de sysadmin y borre el grupo BUILTIN\Administradores para evitar...

Problemas para levantar mirror
  • Topic started by acgch
  • in General
  • 14 years ago.
  • 14 years ago.
  • 16 replies
Hola amigos, tengan un buen día, les comento que estoy configurando mirror siguiendo los pasos a través del wizard del managment studio y también...
Mirroring con estados disconnected
Hola, el día de hoy después de reiniciar mi servidor de destino a donde realizo el mirroring ya no pude replicar más, el error que muestra es que...

Se me duplica el mensaje en /etc/motd
  • Topic started by agamez
  • in General
  • 3 years ago.
  • 3 years ago.
  • 2 replies
Buen día, alguien tiene idea porque después de actualizar a fedora 28 se me esta duplicando la salida de mi /etc/motd?

Cómo puedo filtrar un mensaje en el log messages
Buenos días, estoy recibiendo en mi log de errores muchos mensajes de cron, ya que tengo varios crones configurados en mi server. Existe alguna...

Cómo validar la hora de ejecución de un proceso
Hola, estoy tratando de validar que un proceso sólo pueda ser ejecutado dentro de un periodo de tiempo, en este caso entre las 7:00 AM y las 7:00...

Estadisticas en la base de datos
Buenos días, estoy teniendo problemas de performance en mis queries y quisiera saber como puedo validar que mis tablas tienen las estadisticas...
Deshabilitar todos los jobs
  • Topic started by agamez
  • in Jobs
  • 4 years ago.
  • 4 years ago.
  • 1 reply
Buenos días, alguien sabe como puedo deshabilitar rapidamente todos los jobs de SQL Server, gracias.

Mirroring con estados disconnected
Hola, el día de hoy después de reiniciar mi servidor de destino a donde realizo el mirroring ya no pude replicar más, el error que muestra es que...

Se me duplica el mensaje en /etc/motd
  • Topic started by agamez
  • in General
  • 3 years ago.
  • 3 years ago.
  • 2 replies
Buen día, alguien tiene idea porque después de actualizar a fedora 28 se me esta duplicando la salida de mi /etc/motd?

Cómo puedo filtrar un mensaje en el log messages
Buenos días, estoy recibiendo en mi log de errores muchos mensajes de cron, ya que tengo varios crones configurados en mi server. Existe alguna...

Cómo validar la hora de ejecución de un proceso
Hola, estoy tratando de validar que un proceso sólo pueda ser ejecutado dentro de un periodo de tiempo, en este caso entre las 7:00 AM y las 7:00...