{"id":343,"date":"2017-09-19T22:00:31","date_gmt":"2017-09-19T22:00:31","guid":{"rendered":"http:\/\/www.manualsqlserver.com\/?p=343"},"modified":"2021-03-20T20:12:23","modified_gmt":"2021-03-20T20:12:23","slug":"cursores","status":"publish","type":"post","link":"https:\/\/manualsqlserver.com\/?p=343","title":{"rendered":"Cursores en SQL Server"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/manualsqlserver.com\/wp-content\/uploads\/2020\/05\/ManualSQL_CursoresD.png\" alt=\"\" class=\"wp-image-1012\" width=\"278\" height=\"196\"\/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Cursores<\/strong><\/h3>\n\n\n\n<p>Los cursores permiten almacenar los datos de una consulta T-SQL en memoria y poder manipular los datos de los elementos resultantes para realizar operaciones con ellos. Se recomienda su uso con cierto cuidado porque consume mucha memoria, la instrucci\u00f3n select que llena el cursor debe ser lo m\u00e1s selectiva posible.<\/p>\n\n\n\n<p><strong>Proceso para declarar, abrir, usar, cerrar y liberar los datos de un cursor<\/strong><br>1. Declarar el cursor, utilizando DECLARE Cursor<br>2. Abrir el cursor, utilizando OPEN<br>3. Leer los datos del cursor, utilizando FETCH \u2026 INTO<br>4. Cerrar el cursor, utilizando CLOSE<br>5. Liberar el cursor, utilizando DEALLOCATE<\/p>\n\n\n\n<!--more-->\n\n\n\n<script async=\"\" src=\"\/\/pagead2.googlesyndication.com\/pagead\/js\/adsbygoogle.js\"><\/script>\n<ins class=\"adsbygoogle\" style=\"display:block; text-align:center;\" data-ad-layout=\"in-article\" data-ad-format=\"fluid\" data-ad-client=\"ca-pub-2636008503986218\" data-ad-slot=\"1902193434\"><\/ins>\n<script>\n     (adsbygoogle = window.adsbygoogle || []).push({});\n<\/script>\n\n\n\n<p><strong>Las instrucciones reducidas para los pasos anteriores son:<\/strong><br>1. Para declarar el cursor<\/p>\n\n\n\n<p>DECLARE NombreCursor CURSOR FOR Instrucci\u00f3n Select<\/p>\n\n\n\n<p>2. Abrir el cursor<\/p>\n\n\n\n<p>OPEN NombreDelCursor<\/p>\n\n\n\n<p>3. Lectura de los datos del cursor, va a depender del tipo de cursor. Hay de avance hacia adelante solamente y Scroll.<\/p>\n\n\n\n<p>FETCH NombreDelCursor<\/p>\n\n\n\n<p>Si se va a recorrer el cursor, se debe almacenar los datos de cada registro en variables previamente definidas con la variante siguiente:<\/p>\n\n\n\n<p>FETCH NombreDelCursor INTO ListaVariables<\/p>\n\n\n\n<p>Para lectura de manera autom\u00e1tica de los registros del cursor \u00a0se usa la estructura While, el bucle de esta estructura se ejecutar\u00e1 siempre que la funci\u00f3n<strong> @@FETCH_STATUS <\/strong>sea igual a CERO. La funci\u00f3n @@FETCH_STATUS reporta CERO (0) cuando la instrucci\u00f3n Fetch lee un registro. Al finalizar @@FETCH_STATUS toma el valor de -1.<\/p>\n\n\n\n<p>FETCH NombreDelCursor INTO ListaVariables<br>WHILE (@@FETCH_STATUS = 0)<\/p>\n\n\n\n<p>BEGIN<\/p>\n\n\n\n<p>\u2026 instrucciones del bloque<\/p>\n\n\n\n<p>FETCH  NombreDelCursor   INTO   ListaVariables<br>END \u2014 FIN DEL BUCLE WHILE<\/p>\n\n\n\n<p>4. Cerrar el cursor<\/p>\n\n\n\n<p>CLOSE NombreDelCursor<\/p>\n\n\n\n<p>5. Liberar el espacio de memoria ocupado por el cursor<\/p>\n\n\n\n<p>DEALLOCATE NombreDelCursor<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Ejercicios<\/h3>\n\n\n\n<p style=\"font-size:24px\"><strong>Ejercicio 1<\/strong><\/p>\n\n\n\n<p><strong>Cursor que reporta los Empleados<\/strong><br>Declare cursorEmpleados cursor for<br>select EmployeeID, LastName, FirstName from Employees<br>go<br><strong>&#8212; Abrir el cursor<\/strong><br>open cursorEmpleados<br>go<br><strong>&#8212; Los datos disponibles se visualizar con Fetch, ejecutar varias veces para ver los resultados.<\/strong><br>Fetch cursorEmpleados<br>go<br>&#8212; La funci\u00f3n @@FETCH_STATUS reporta CERO si hay registro<br>&#8212; reporta -1 si ya no existen registros para mostrar<br>select @@FETCH_STATUS<br>go<br><strong>&#8212; Cerrar el cursor, liberar de memoria<\/strong><br>close cursorEmpleados<br>Deallocate cursorEmpleados<br>go<\/p>\n\n\n\n<p style=\"font-size:24px\"><strong>Ejercicio 2<\/strong><\/p>\n\n\n\n<p><strong>Cursor que reporte la lista de productos, si las unidades en orden son mayores al stock, mostrar COMPRAR URGENTE, de lo contrario mostrar STOCK ADECUADO<\/strong><br><strong>Nota: El ejercicio muestra mensajes, los que en la pr\u00e1ctica no son realmente \u00fatiles.<\/strong><\/p>\n\n\n\n<p>Declare cursorProductoComprasUrgente cursor for<br>SELECT P.ProductID, P.ProductName,<br>P.UnitsInStock, P.UnitsOnOrder<br>from Products As P<br>Open cursorProductoComprasUrgente<br>Declare @Codigo int, @Descripcion nvarchar(40),<br>@Stock Numeric(9,2), @PorAtender Numeric(9,2)<br>Fetch cursorProductoComprasUrgente into @Codigo,<br>@Descripcion, @Stock, @PorAtender<br>Print &#8216;================ LISTADO ======================&#8217;<br>While (@@FETCH_STATUS = 0)<br>Begin<br>Declare @Mensaje nvarchar(20)<br>If (@PorAtender &gt; @Stock)<br>Begin<br>Set @Mensaje = &#8216;COMPRAR URGENTE&#8217;<br>End<br>Else<br>Begin<br>Set @Mensaje = &#8216;STOCK ADECUADO&#8217;<br>End<br>&#8212; reportar el registro y luego leer el siguiente<\/p>\n\n\n\n<p>Print &#8216;C\u00f3digo: &#8216; + STR(@Codigo)<br>Print &#8216;Descripci\u00f3n: &#8216; + @Descripcion + &#8216; Stock: &#8216; + Ltrim(STR(@Stock)) + &#8216; Por Atender: &#8216; + Ltrim(Str(@PorAtender))<br>Print &#8216;Mensaje: &#8216; + @Mensaje<br>Print \u00bb<br>Print &#8216;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8216;<br>Fetch cursorProductoComprasUrgente into @Codigo,<br>@Descripcion, @Stock, @PorAtender<br>End<br>Close cursorProductoComprasUrgente<br>Deallocate cursorProductoComprasUrgente<br>go<\/p>\n\n\n\n<p>El resultado se muestra en la siguiente imagen<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><a href=\"https:\/\/manualsqlserver.com\/wp-content\/uploads\/2021\/03\/ManualSQL_Cursores_01.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/manualsqlserver.com\/wp-content\/uploads\/2021\/03\/ManualSQL_Cursores_01.png\" alt=\"\" class=\"wp-image-2534\" width=\"931\" height=\"627\" srcset=\"https:\/\/manualsqlserver.com\/wp-content\/uploads\/2021\/03\/ManualSQL_Cursores_01.png 992w, https:\/\/manualsqlserver.com\/wp-content\/uploads\/2021\/03\/ManualSQL_Cursores_01-300x202.png 300w, https:\/\/manualsqlserver.com\/wp-content\/uploads\/2021\/03\/ManualSQL_Cursores_01-768x517.png 768w, https:\/\/manualsqlserver.com\/wp-content\/uploads\/2021\/03\/ManualSQL_Cursores_01-795x535.png 795w\" sizes=\"auto, (max-width: 931px) 100vw, 931px\" \/><\/a><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Cursor de tipo Scroll<\/strong><\/h3>\n\n\n\n<p>Para un cursor de tipo Scroll se pueden usar:&nbsp; Firts, Next, Prior, Last, Relative n,<br>Absolute n para mostrar los diferentes registros.<\/p>\n\n\n\n<p><strong>Cursor Scroll para Categorias<\/strong><\/p>\n\n\n\n<p>Declare cursorCategorias <strong>Scroll<\/strong> cursor<br>for select * from Categories<br>Open cursorCategorias<br>go<\/p>\n\n\n\n<p>Note que en la definici\u00f3n del cursor se ha utilizado la palabra Scroll.<\/p>\n\n\n\n<p><strong>&#8212; Mostrar los datos<\/strong><br>Fetch cursorCategorias<br>go<br><strong>&#8212; Registro 6<\/strong><br>Fetch Absolute 6 from cursorCategorias<br>go<br><strong>&#8212; Siguiente<\/strong><br>Fetch Next from cursorCategorias<br>go<br><strong>&#8212; Anterior<\/strong><br>Fetch Prior from cursorCategorias<br>go<br><strong>&#8212; \u00daltimo<\/strong><br>Fetch Last from cursorCategorias<br>go<br><strong>&#8212; Tres anteriores<\/strong><br>Fetch Relative -3 from cursorCategorias<br>go<br><strong>&#8212; Dos hacia adelante<\/strong><br>Fetch Relative 2 from cursorCategorias<br>go<br><strong>&#8212; Primero<\/strong><br>Fetch First from cursorCategorias<br>go<br><strong>&#8212; Cerrar y Liberar<\/strong><br>Close cursorCategorias<br>Deallocate cursorCategorias<br>go<\/p>\n\n\n\n<script async=\"\" src=\"\/\/pagead2.googlesyndication.com\/pagead\/js\/adsbygoogle.js\"><\/script>\n<ins class=\"adsbygoogle\" style=\"display:block; text-align:center;\" data-ad-layout=\"in-article\" data-ad-format=\"fluid\" data-ad-client=\"ca-pub-2636008503986218\" data-ad-slot=\"1902193434\"><\/ins>\n<script>\n     (adsbygoogle = window.adsbygoogle || []).push({});\n<\/script>\n\n\n\n<h2 class=\"wp-block-heading\">Cursores anidados<\/h2>\n\n\n\n<p><strong>&#8212; Listado de las categor\u00edas y sus productos<\/strong><\/p>\n\n\n\n<p>Declare cursorCategoriasListadoProductos cursor for<br>select C.CategoryID, C.CategoryName from Categories As C<\/p>\n\n\n\n<p>Open cursorCategoriasListadoProductos<\/p>\n\n\n\n<p>Declare @CodigoCategoria int, @NombreCategoria nvarchar(15)<br>Fetch cursorCategoriasListadoProductos into @CodigoCategoria, @NombreCategoria<\/p>\n\n\n\n<p>Print &#8216;============================================================&#8217;<br>Print &#8216;============ Listado de Productos por categoria ==========&#8217;<br>Print &#8216;============================================================&#8217;<br>Print \u00bb<\/p>\n\n\n\n<p>While (@@FETCH_STATUS = 0) &#8212; Recorre el cursor de Categor\u00edas<\/p>\n\n\n\n<p>Begin<\/p>\n\n\n\n<p>Print &#8216;C\u00f3digo Categoria: &#8216; + Ltrim(Str(@CodigoCategoria)) + Space(2) +<br>&#8216;Categor\u00eda: &#8216; + @NombreCategoria<br>&#8212; Definir el Cursor para los productos &#8211; CURSOR ANIDADO<br>Declare cursorProductosCategoria cursor for<br>select P.ProductID, P.ProductName, P.UnitPrice from Products As P<br>where P.CategoryID = @CodigoCategoria<br>Open cursorProductosCategoria<br>Declare @CodigoProducto int, @NombreProducto nvarchar(40),<br>@Precio Numeric(9,2)<br>Fetch cursorProductosCategoria into @CodigoProducto, @NombreProducto, @Precio<br>Print \u00bb<br>Print &#8216;====================== PRODUCTOS ==========================&#8217;<br>Print &#8216; CODIGO DESCRIPCION PRECIO &#8216;<\/p>\n\n\n\n<p>While (@@FETCH_STATUS = 0) &#8212; Estructura para Productos<\/p>\n\n\n\n<p>Begin<\/p>\n\n\n\n<p>Print Space(5) + Ltrim(str(@CodigoProducto)) + Space(10) + @NombreProducto + space(20) + Ltrim(str(@Precio))<br>Fetch cursorProductosCategoria into @CodigoProducto, @NombreProducto, @Precio<\/p>\n\n\n\n<p>End &#8212; Final While de Productos<\/p>\n\n\n\n<p>Print \u00bb<br>Close cursorProductosCategoria<br>Deallocate cursorProductosCategoria<\/p>\n\n\n\n<p>&#8212; Leer la siguiente categoria<br>Fetch cursorCategoriasListadoProductos into @CodigoCategoria, @NombreCategoria<\/p>\n\n\n\n<p>End &#8212; Final While de Categorias<\/p>\n\n\n\n<p>Close cursorCategoriasListadoProductos<br>Deallocate cursorCategoriasListadoProductos<br>go<\/p>\n\n\n\n<p><strong>Incluir Cantidad de Productos, Valor del Stock por categoria<\/strong><br><strong>Cantidad Total del Productos y Valor total del Stock<\/strong><br><strong>Es necesario usar Acumuladores.<\/strong><br>Declare cursorCategorias cursor for<br>select CategoryID, CategoryName from Categories<br>Open cursorCategorias<br>Declare @CodigoCategoria Integer, @NombreCategoria nvarchar(15)<br>Fetch cursorCategorias into @CodigoCategoria, @NombreCategoria<\/p>\n\n\n\n<p>Declare @CantidadTotaldeProductos Numeric(9,2), @ValorTotaldelStock Numeric(9,2) &#8212; Variables para totales<br>set @CantidadTotaldeProductos = 0<br>Set @ValorTotaldelStock = 0<\/p>\n\n\n\n<p>Print &#8216;=====================================&#8217;<br>Print &#8216;=====PRODUCTOS POR CATEGORIA=========&#8217;<br>Print &#8216;=====================================&#8217;<br>While (@@FETCH_STATUS = 0)<br>Begin<br>Print &#8216;C\u00f3digo Categoria: &#8216; + Ltrim(Str(@CodigoCategoria))<br>Print &#8216;Nombre Categoria: &#8216; + Ltrim(@NombreCategoria)<br>Print &#8216;===================================================&#8217;<br>&#8212; Definir el cursor para los productos de la categoria actual<br>Declare cursorProductoPorCategoria cursor for<br>select ProductID, ProductName, UnitPrice, UnitsInStock from Products<br>where CategoryID = @CodigoCategoria<br>Open cursorProductoPorCategoria<br>Declare @CodigoProducto Integer, @NombreProducto nvarchar(40), @Precio Numeric(9,2), @Stock Numeric(9,2)<br>Fetch cursorProductoPorCategoria into @CodigoProducto, @NombreProducto, @Precio, @Stock<\/p>\n\n\n\n<p>Declare @CantidadProductosPorCategoria Numeric(9,2), @ValorStockPorCategoria Numeric(9,2)<br>Set @CantidadProductosPorCategoria = 0<br>Set @ValorStockPorCategoria = 0<\/p>\n\n\n\n<p>While (@@FETCH_STATUS = 0) &#8212; Para Productos<br>Begin<br>Print &#8216;C\u00f3digo: &#8216; + Ltrim(Str(@CodigoProducto)) + &#8216; Descripci\u00f3n: &#8216; + Ltrim(@NombreProducto)<\/p>\n\n\n\n<p>&#8212; Acumular<br>Set @CantidadProductosPorCategoria = @CantidadProductosPorCategoria + @Stock<br>Set @ValorStockPorCategoria = @ValorStockPorCategoria + @Precio* @Stock<\/p>\n\n\n\n<p>Fetch cursorProductoPorCategoria into @CodigoProducto, @NombreProducto, @Precio,@Stock<br>End<br>Print &#8216;Cantidad Productos: &#8216; + Ltrim(Str(@CantidadProductosPorCategoria))<br>Print &#8216;Valor del Stock: &#8216; + Ltrim(Str(@ValorStockPorCategoria))<\/p>\n\n\n\n<p>Close cursorProductoPorCategoria<br>Deallocate cursorProductoPorCategoria<br>Print \u00bb<br>&#8212; Acumulado Total<br>Set @CantidadTotaldeProductos = @CantidadTotaldeProductos + @CantidadProductosPorCategoria<br>Set @ValorTotaldelStock = @ValorTotaldelStock + @ValorStockPorCategoria<\/p>\n\n\n\n<p>Fetch cursorCategorias into @CodigoCategoria, @NombreCategoria<br>End<br>Print &#8216;Cantidad Total Productos: &#8216; + Ltrim(Str(@CantidadTotaldeProductos))<br>Print &#8216;Valor Total del Stock: &#8216; + Ltrim(Str(@ValorTotaldelStock))<\/p>\n\n\n\n<p>Close cursorCategorias<br>Deallocate cursorCategorias<br>go<\/p>\n\n\n\n<p>El resultado se muestra para la primera categor\u00eda en la siguiente imagen<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/manualsqlserver.com\/wp-content\/uploads\/2020\/05\/ManualSQL_Cursores01.png\" alt=\"\" class=\"wp-image-1011\" width=\"752\" height=\"587\" srcset=\"https:\/\/manualsqlserver.com\/wp-content\/uploads\/2020\/05\/ManualSQL_Cursores01.png 525w, https:\/\/manualsqlserver.com\/wp-content\/uploads\/2020\/05\/ManualSQL_Cursores01-300x234.png 300w\" sizes=\"auto, (max-width: 752px) 100vw, 752px\" \/><\/figure><\/div>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Cursores Los cursores permiten almacenar los datos de una consulta T-SQL en memoria y poder manipular los datos de los elementos resultantes para realizar operaciones con ellos. Se recomienda su uso con cierto cuidado porque consume mucha memoria, la instrucci\u00f3n select que llena el cursor debe ser lo m\u00e1s selectiva posible. Proceso para declarar, abrir, &hellip; <\/p>\n<p><a class=\"more-link btn\" href=\"https:\/\/manualsqlserver.com\/?p=343\">Seguir leyendo<\/a><\/p>\n","protected":false},"author":1,"featured_media":1012,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[232,8],"tags":[71,53],"class_list":["post-343","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cursoressql","category-programacion","tag-cursores-en-sql-server","tag-sqlserver","nodate","item-wrap"],"_links":{"self":[{"href":"https:\/\/manualsqlserver.com\/index.php?rest_route=\/wp\/v2\/posts\/343","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/manualsqlserver.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/manualsqlserver.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/manualsqlserver.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/manualsqlserver.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=343"}],"version-history":[{"count":2,"href":"https:\/\/manualsqlserver.com\/index.php?rest_route=\/wp\/v2\/posts\/343\/revisions"}],"predecessor-version":[{"id":2535,"href":"https:\/\/manualsqlserver.com\/index.php?rest_route=\/wp\/v2\/posts\/343\/revisions\/2535"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/manualsqlserver.com\/index.php?rest_route=\/wp\/v2\/media\/1012"}],"wp:attachment":[{"href":"https:\/\/manualsqlserver.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=343"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/manualsqlserver.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=343"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/manualsqlserver.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=343"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}