Implementaciones de cursores

Microsoft SQL Server admite tres implementaciones de cursores:

  • Cursores de Transact-SQL
    Estos cursores se basan en la sintaxis DECLARE CURSOR y se utilizan principalmente en scripts, procedimientos almacenados y desencadenadores de Transact-SQL. Los cursores Transact-SQL se implementan en el servidor y se administran mediante instrucciones Transact-SQL enviadas del cliente al servidor. También se pueden encontrar en lotes, procedimientos almacenados o desencadenadores.

  • Cursores de servidor de la API (Interfaz de programación de aplicaciones)
    Permiten las funciones de cursor de la API con OLE DB y ODBC. Los cursores de servidor de la API están implementados en el servidor. Cada vez que una aplicación cliente llama a una función de cursor de la API, el proveedor OLE DB de SQL Server Native Client o el controlador de ODBC transmite la solicitud al servidor para que realice una acción con el cursor de servidor de la API.

  • Cursores del cliente
    Los implementan internamente el controlador ODBC de SQL Server Native Client y la DLL que implementa la API ADO. Los cursores del cliente se implementan almacenando en caché todas las filas de conjuntos de resultados del cliente. Cada vez que una aplicación cliente llama a una función de cursor de la API, el controlador ODBC de SQL Server Native Client o la DLL de ADO realizan la operación de cursor en las filas del conjunto de resultados almacenadas en la caché del cliente.

Los cursores de Transact-SQL y los cursores de servidor de la API se implementan en el servidor, por lo que se denominan colectivamente cursores de servidor.

No mezcle los distintos tipos de cursores. Si ejecuta una instrucción DECLARE CURSOR y una instrucción OPEN desde una aplicación, establezca primero los atributos de cursor de la API en sus valores predeterminados. Si establece los atributos de un cursor de la API en un valor distinto de los predeterminados y, a continuación, ejecuta una instrucción DECLARE CURSOR y una instrucción OPEN, está pidiendo a SQL Server que asigne un cursor de la API sobre un cursor de Transact-SQL. Por ejemplo, no establezca los atributos de ODBC que requieren que se asigne un cursor controlado por conjunto de claves sobre un conjunto de resultados para utilizar a continuación ese identificador de instrucción para ejecutar DECLARE CURSOR y OPEN y llamar a un cursor INSENSITIVE.

El hecho de que los cursores de servidor no admitan actualmente todas las instrucciones Transact-SQL puede representar un inconveniente. Los cursores de servidor no admiten las instrucciones Transact-SQL que generan múltiples conjuntos de resultados, por lo que no se pueden utilizar cuando la aplicación ejecuta un procedimiento almacenado o un lote que contiene más de una instrucción SELECT. Los cursores de servidor tampoco admiten instrucciones de SQL que contengan las palabras clave COMPUTE, COMPUTE BY, FOR BROWSE o INTO.

Cursores de servidor y conjuntos de resultados predeterminados

Un cursor resulta menos eficaz que un conjunto de resultados predeterminado. En un conjunto de resultados predeterminado, el único paquete que se envía desde el cliente al servidor es el que contiene la instrucción que se va a ejecutar. Cuando se utiliza un cursor de servidor, es preciso enviar cada instrucción FETCH desde el cliente al servidor, donde se analizará y compilará en un plan de ejecución.

Si una instrucción Transact-SQL devuelve un conjunto de resultados relativamente pequeño, que se puede almacenar en la caché de la memoria disponible de la aplicación cliente, y sabe antes de ejecutar la instrucción que deberá recuperar el conjunto de resultados completo, utilice un conjunto de resultados predeterminado. Utilice cursores de servidor únicamente cuando se necesiten operaciones de cursores para admitir la funcionalidad de la aplicación o cuando probablemente sólo se pueda recuperar una parte del conjunto de resultados.

Cursores de servidor y cursores del cliente

La utilización de cursores de servidor en lugar de cursores del cliente conlleva varias ventajas:

  • Rendimiento

    Si desea obtener acceso a una parte de los datos del cursor (acción habitual en la mayoría de las aplicaciones de exploración), los cursores de servidor proporcionan un rendimiento óptimo, porque sólo se envían a través de la red los datos recopilados. Los cursores del cliente almacenan en la caché del cliente el conjunto de resultados completo.

  • Tipos de cursor adicionales

    Si el controlador de ODBC de SQL Server Native Client sólo utiliza cursores del cliente, únicamente podrá admitir cursores de sólo avance y estáticos. Si utiliza cursores de servidor de la API, el controlador también admitirá cursores controlados por conjunto de claves y cursores dinámicos. SQL Server también admite el intervalo completo de los atributos de simultaneidad para cursores, pero sólo a través de cursores de servidor. Las funciones que admiten los cursores del cliente están limitadas.

  • Actualizaciones posicionadas más precisas

    Los cursores de servidor admiten directamente operaciones por posición, como la función SQLSetPos de ODBC o las instrucciones UPDATE y DELETE con la cláusula WHERE CURRENT OF. Por otra parte, los cursores del cliente simulan las actualizaciones de cursor por posición generando una instrucción UPDATE buscada mediante Transact-SQL, lo que realizará actualizaciones no deseadas si más de una fila cumple las condiciones de la cláusula WHERE de la instrucción UPDATE.

  • Uso de la memoria

    Cuando se utilizan cursores de servidor, no es preciso que el cliente almacene en caché grandes cantidades de datos ni mantenga información acerca de la posición del cursor, puesto que el servidor se encarga de ello.

  • Varias instrucciones activas

    Cuando se utilizan cursores de servidor, no queda pendiente ningún resultado en la conexión entre operaciones de cursores. Esto permite tener activas al mismo tiempo varias instrucciones basadas en cursores.

El funcionamiento de todos los cursores de servidor, excepto los estáticos o INSENSITIVE, depende del esquema de las tablas subyacentes. La modificación del esquema de estas tablas una vez declarado un cursor provocará errores en las operaciones posteriores del cursor.