Usar el tipo de datos cursor en un parámetro OUTPUT

Los procedimientos almacenados de Transact-SQL sólo pueden utilizar el tipo de datos cursor para los parámetros OUTPUT. Si se especifica el tipo de datos cursor para un parámetro, se requieren también los parámetros VARYING y OUTPUT. Si se especifica la palabra clave VARYING para un parámetro, el tipo de datos deberá ser cursor y se deberá especificar la palabra clave OUTPUT.

[!NOTA]

El tipo de datos cursor no se puede enlazar a variables de aplicación a través de las API de bases de datos tales como OLE DB, ODBC, ADO y DB-Library. Debido a que los parámetros OUTPUT deben estar enlazados antes de que una aplicación pueda ejecutar un procedimiento almacenado, dichos procedimientos con parámetros cursor OUTPUT no pueden llamarse desde las API de bases de datos. Estos procedimientos sólo pueden llamarse desde procesos por lotes, procedimientos almacenados o desencadenadores Transact-SQL cuando la variable cursor OUTPUT esté asignada a una variable cursor local de Transact-SQL.

Parámetros cursor OUTPUT

Las siguientes reglas se aplican a los parámetros cursor OUTPUT cuando se ejecuta el procedimiento:

  • Para un cursor de sólo avance, las filas devueltas en el conjunto de resultados del cursor son sólo aquellas filas que estén en la posición del cursor y hacia adelante al concluir la ejecución del procedimiento almacenado, por ejemplo:

    • En un procedimiento de un conjunto de resultados llamado RS de 100 filas, se abre un cursor no desplazable.

    • El procedimiento recupera las primeras 5 filas del conjunto de resultados RS.

    • El procedimiento vuelve a quien le llamó.

    • El conjunto de resultados que RS devolvió a quien llamó está formado por las filas 6 a 100 de RS; el cursor del que llama se coloca antes de la primera fila de RS.

  • Para un cursor de sólo avance, si el cursor se coloca antes de la primera fila una vez que finalice el procedimiento almacenado, el conjunto de resultados completo se devuelve al proceso por lotes, procedimiento almacenado o desencadenador que lo llamó. Cuando se devuelve, la posición del cursor se establece antes de la primera fila.

  • Para un cursor de sólo avance, si el cursor se coloca después del final de la última fila una vez que finalice el procedimiento almacenado, se devolverá un conjunto de resultados vacío al proceso por lotes, procedimiento almacenado o desencadenador que lo llamó.

    [!NOTA]

    Un conjunto de resultados vacío no es lo mismo que un valor NULL.

  • Para un cursor desplazable, todas las filas del conjunto de resultados se devuelven al proceso por lotes, procedimiento almacenado o desencadenador que llama cuando finaliza la ejecución del procedimiento almacenado. Cuando se devuelve, la posición del cursor se deja en la posición de la última recuperación ejecutada en el procedimiento.

  • Para cualquier tipo de cursor, si se ha cerrado el cursor, se devuelve un valor NULL al proceso por lotes, procedimiento almacenado o desencadenador que lo llamó. Esto también ocurrirá si se ha asignado un cursor a un parámetro, pero ese cursor nunca se abre.

    [!NOTA]

    El estado cerrado sólo tiene importancia en el momento del retorno. Por ejemplo, es válido cerrar un cursor a mitad del procedimiento, volver a abrirlo posteriormente en el procedimiento y devolver el conjunto de resultados de ese cursor al proceso por lotes, procedimiento almacenado o desencadenador que lo llamó.

Ejemplo

En el siguiente ejemplo, se crea un procedimiento almacenado que especifica un parámetro OUTPUT, @currency\_cursor, con el tipo de datos cursor. A continuación, se llama al procedimiento almacenado desde un lote.

Primero, crea el procedimiento de declaración y, luego, abre un cursor en la tabla Currency.

USE AdventureWorks;
GO
IF OBJECT_ID ( 'dbo.uspCurrencyCursor', 'P' ) IS NOT NULL
    DROP PROCEDURE dbo.uspCurrencyCursor;
GO
CREATE PROCEDURE dbo.uspCurrencyCursor 
    @CurrencyCursor CURSOR VARYING OUTPUT
AS
    SET NOCOUNT ON;
    SET @CurrencyCursor = CURSOR
    FORWARD_ONLY STATIC FOR
      SELECT CurrencyCode, Name
      FROM Sales.Currency;
    OPEN @CurrencyCursor;
GO

A continuación, se ejecuta un proceso por lotes que declara una variable cursor local, ejecuta el procedimiento para asignar el cursor a la variable local y, por último, recupera las filas desde el cursor.

USE AdventureWorks;
GO
DECLARE @MyCursor CURSOR;
EXEC dbo.uspCurrencyCursor @CurrencyCursor = @MyCursor OUTPUT;
WHILE (@@FETCH_STATUS = 0)
BEGIN;
     FETCH NEXT FROM @MyCursor;
END;
CLOSE @MyCursor;
DEALLOCATE @MyCursor;
GO