En informática , un cursor de base de datos es un mecanismo que permite recorrer los registros de una base de datos. Los cursores facilitan el procesamiento asociado al recorrido, como la recuperación, la adición y la eliminación de registros. Esta característica de recorrido hace que los cursores sean similares al concepto de iterador en los lenguajes de programación .
Los programadores de bases de datos utilizan cursores para procesar filas individuales devueltas por las consultas del sistema . Los cursores permiten manipular conjuntos de resultados completos a la vez. En este caso, un cursor posibilita el procesamiento secuencial de las filas de un conjunto de resultados.
En los procedimientos SQL, un cursor permite definir un conjunto de resultados (un conjunto de filas de datos) y ejecutar lógica compleja fila por fila. Mediante este mismo mecanismo, un procedimiento SQL también puede definir un conjunto de resultados y devolverlo directamente a quien lo invocó o a una aplicación cliente.
Un cursor puede considerarse como un puntero a una fila dentro de un conjunto de filas. El cursor solo puede hacer referencia a una fila a la vez, pero puede moverse a otras filas del conjunto de resultados según sea necesario.
Uso
Para utilizar cursores en procedimientos SQL, debe hacer lo siguiente:
- Declara un cursor que defina un conjunto de resultados.
- Abra el cursor para establecer el conjunto de resultados.
- Obtenga los datos en variables locales según sea necesario desde el cursor, una fila a la vez.
- Cierra el cursor cuando hayas terminado.
Para trabajar con cursores, debe utilizar las siguientes sentencias SQL.
Esta sección presenta la forma en que el estándar SQL:2003 define cómo usar cursores en aplicaciones SQL embebidas. No todas las interfaces de aplicaciones para sistemas de bases de datos relacionales se adhieren a ese estándar, y algunas (como CLI o JDBC ) usan una interfaz diferente.
Un programador hace que un cursor sea conocido por el DBMS mediante una instrucción DECLARE... CURSORy asignándole al cursor un nombre (obligatorio):
DECLARE cursor_name CURSOR IS SELECT ... FROM ...
Antes de que el código pueda acceder a los datos, debe abrir el cursor con la OPENinstrucción correspondiente. Inmediatamente después de abrirlo correctamente, el cursor se posiciona antes de la primera fila del conjunto de resultados.
ABRIR nombre_del_cursor
Las aplicaciones posicionan cursores en una fila específica del conjunto de resultados mediante esta FETCHinstrucción. Una operación de recuperación transfiere los datos de la fila a la aplicación.
OBTENER cursor_name EN ...
Una vez que una aplicación ha procesado todas las filas disponibles o la operación de recuperación debe posicionarse en una fila inexistente (compárese con los cursores desplazables a continuación), el DBMS devuelve un SQLSTATE '02000' (generalmente acompañado de un SQLCODE +100) para indicar el final del conjunto de resultados.
El último paso consiste en cerrar el cursor utilizando la CLOSEinstrucción:
CERRAR nombre_del_cursor
Tras cerrar un cursor, un programa puede volver a abrirlo, lo que implica que el sistema de gestión de bases de datos (DBMS) vuelve a evaluar la misma consulta o una diferente y genera un nuevo conjunto de resultados.
Cursores desplazables
Los programadores pueden declarar los cursores como desplazables o no desplazables. La capacidad de desplazamiento indica la dirección en la que se puede mover un cursor.
Con un cursor no desplazable (o de solo avance ), puede recorrer FETCHcada fila como máximo una vez, y el cursor se mueve automáticamente a la siguiente fila. Después de obtener la última fila, si la vuelve a obtener, colocará el cursor después de la última fila y obtendrá el siguiente código: SQLSTATE 02000 (SQLCODE +100).
Un programa puede posicionar un cursor desplazable en cualquier parte del conjunto de resultados mediante la FETCHinstrucción SQL. La palabra clave SCROLL debe especificarse al declarar el cursor. El valor predeterminado es NO SCROLL, aunque diferentes enlaces de lenguaje como JDBC pueden aplicar un valor predeterminado diferente.
DECLARE cursor_name sensitivity SCROLL CURSOR FOR SELECT ... FROM ...
La posición de destino de un cursor desplazable se puede especificar de forma relativa (desde la posición actual del cursor) o absoluta (desde el principio del conjunto de resultados).
OBTENER [ SIGUIENTE | ANTERIOR | PRIMERO | ÚLTIMO ] DESDE nombre_del_cursor
OBTENER ABSOLUTO n DESDE nombre_del_cursor
OBTENER RELATIVO n DESDE cursor_name ;
Los cursores desplazables pueden acceder varias veces a la misma fila del conjunto de resultados. Por lo tanto, las modificaciones de datos (operaciones de inserción, actualización y eliminación) de otras transacciones podrían afectar al conjunto de resultados. Un cursor puede ser sensible o insensible a dichas modificaciones. Un cursor sensible detecta las modificaciones de datos que afectan al conjunto de resultados del cursor, mientras que un cursor insensible no. Además, un cursor puede ser insensible; en ese caso, el sistema de gestión de bases de datos (DBMS) intenta aplicar la mayor sensibilidad posible.
"CON RETENCIÓN"
Los cursores suelen cerrarse automáticamente al finalizar una transacción, es decir, cuando se produce un COMMIT o un ROLLBACK (o una terminación implícita de la transacción). Este comportamiento puede modificarse si el cursor se declara mediante la cláusula WITH HOLD (el valor predeterminado es WITHOUT HOLD). Un cursor que admite retención permanece abierto tras un COMMIT y se cierra tras un ROLLBACK. (Algunos sistemas de gestión de bases de datos se desvían de este comportamiento estándar y también mantienen abiertos los cursores que admiten retención tras un ROLLBACK).
DECLARE cursor_name CURSOR WITH HOLD FOR SELECT .... FROM ....
Cuando se produce una confirmación (COMMIT), se coloca un cursor retenido antes de la siguiente fila. Por lo tanto, una instrucción UPDATE o DELETE posicionada solo tendrá éxito después de que se haya producido una operación FETCH en la transacción.
Tenga en cuenta que JDBC define los cursores como retenibles por defecto. Esto se debe a que JDBC también activa la confirmación automática por defecto.
Sentencias de actualización/eliminación posicionadas
Los cursores no solo se pueden usar para recuperar datos del sistema de gestión de bases de datos (DBMS) e insertarlos en una aplicación, sino también para identificar una fila en una tabla que se va a actualizar o eliminar. El estándar SQL:2003 define las sentencias SQL de actualización y eliminación posicionadas para este propósito. Dichas sentencias no utilizan una cláusula WHERE regular con predicados. En su lugar, un cursor identifica la fila. El cursor debe abrirse y posicionarse previamente en una fila mediante una FETCHsentencia SQL.
ACTUALIZAR nombre_tabla COLOCAR ... DONDE ACTUAL DE nombre_del_cursor
BORRAR FROM table_name WHERE CURRENT OF cursor_name
El cursor debe operar sobre un conjunto de resultados actualizable para poder ejecutar correctamente una instrucción de actualización o eliminación posicional. De lo contrario, el sistema de gestión de bases de datos (DBMS) no sabría cómo aplicar los cambios de datos a las tablas subyacentes a las que hace referencia el cursor.
Cursores en transacciones distribuidas
El uso de cursores en transacciones distribuidas ( entornos X/Open XA ), que se controlan mediante un monitor de transacciones, no difiere del uso de cursores en transacciones no distribuidas.
Sin embargo, es importante prestar atención al usar cursores sostenibles . Las conexiones pueden ser utilizadas por diferentes aplicaciones. Por lo tanto, una vez que una transacción ha finalizado y se ha confirmado, una transacción posterior (que se ejecuta en una aplicación diferente) podría heredar los cursores sostenibles existentes. En consecuencia, el desarrollador de la aplicación debe tener en cuenta esta situación.
Cursores en XQuery
El lenguaje XQuery permite crear cursores utilizando la función subsequence() .
El formato es:
let $ displayed-sequence := subsequence ( $ result , $ start , $ item-count )Donde $ resultado es el resultado de la consulta XQuery inicial, $inicio es el número de elemento con el que empezar y $contador de elementos es el número de elementos que se van a devolver.
De forma equivalente, esto también se puede hacer utilizando un predicado:
let $ displayed-sequence := $ result [ $ start to $ end ]¿Dónde $endestá la secuencia final?
Para ver ejemplos completos, consulte XQuery/Searching,Paging and Sorting#Paging en Wikibooks .![]()
Desventajas de los cursores
La siguiente información puede variar según el sistema de base de datos específico.
La recuperación de una fila desde el cursor puede implicar un viaje de ida y vuelta a la red cada vez. Esto consume mucho más ancho de banda del que normalmente se necesitaría para la ejecución de una sola instrucción SQL como DELETE. Los viajes de ida y vuelta repetidos a la red pueden reducir drásticamente la velocidad de la operación que utiliza el cursor. Algunos sistemas de gestión de bases de datos (DBMS) intentan mitigar este efecto mediante la recuperación por bloques. La recuperación por bloques implica que se envían varias filas juntas desde el servidor al cliente. El cliente almacena un bloque completo de filas en un búfer local y las recupera desde allí hasta que se agota dicho búfer.
Los cursores asignan recursos en el servidor, como bloqueos , paquetes, procesos y almacenamiento temporal. Por ejemplo, Microsoft SQL Server implementa los cursores creando una tabla temporal y rellenándola con el conjunto de resultados de la consulta. Si un cursor no se cierra correctamente ( no se libera ), los recursos no se liberarán hasta que se cierre la sesión SQL (conexión). Este desperdicio de recursos en el servidor puede provocar una disminución del rendimiento y fallos.
Ejemplo
MESA DE EMPLEADOS
SQL > desc DETALLES_EMPLEADOS ; Nombre ¿Nulo? Tipo --------------- -------- ------------ ID_EMPLEADO NO NULO NÚMERO(6) NOMBRE VARCHAR2(20) APELLIDO NO NULO VARCHAR2(25) CORREO_ELECTRÓNICO NO NULO VARCHAR2(30) NÚMERO_TELÉFONO VARCHAR2(20) FECHA_CONTRATACIÓN NO NULO FECHA ID_TRABAJO NO NULO VARCHAR2(10) SALARIO NÚMERO(8,2) PORCENTAJE_COMISIÓN NÚMERO(2,2) ID_GERENTE NÚMERO(6) ID_DEPARTAMENTO NÚMERO(4)CURSOR DE MUESTRA CONOCIDO COMO EECREAR O REEMPLAZAR EL PROCEDIMIENTO EE COMO INICIODECLARE v_employeeID EMPLOYEES_DETAILS . EMPLOYEE_ID %TYPE ; v_FirstName EMPLOYEES_DETAILS . FIRST_NAME %TYPE ; v_LASTName EMPLOYEES_DETAILS . LAST_NAME %TYPE ; v_JOB_ID EMPLOYEES_DETAILS . JOB_ID %TYPE := 'IT_PROG' ;Cursor c_EMPLOYEES_DETAILS IS SELECT EMPLOYEE_ID , FIRST_NAME , LAST_NAME FROM EMPLOYEES_DETAILS WHERE JOB_ID = 'v_JOB_ID' ;COMIENZA ABRIR c_EMPLOYEES_DETAILS ;BUCLEOBTENER c_EMPLOYEES_DETAILS EN v_employeeID , v_FirstName , v_LASTName ;DBMS_OUTPUT.put_line ( v_employeeID ) ; DBMS_OUTPUT.put_line ( v_FirstName ) ; DBMS_OUTPUT.put_line ( v_LASTName ) ;SALIR CUANDO c_EMPLOYEES_DETAILS %NOTFOUND ; FIN DEL BUCLE ;CERRAR c_EMPLOYEES_DETAILS ; FIN ;FIN ;Véase también
Referencias
- Christopher J. Date : Base de datos en profundidad , O'Reilly & Associates, ISBN 0-596-10012-4
- Thomas M. Connolly , Carolyn E. Begg : Sistemas de bases de datos , Addison-Wesley, ISBN 0-321-21025-5
- Ramiz Elmasri , Shamkant B. Navathe : Fundamentos de los sistemas de bases de datos , Addison-Wesley, ISBN 0-201-54263-3
- Neil Matthew , Richard Stones : Introducción a las bases de datos con PostgreSQL: De principiante a profesional , Apress, ISBN 1-59059-478-9
- Thomas Kyte : Asesoramiento personalizado con un experto: Oracle , Apress, ISBN 1-59059-525-4
- Kevin Loney: Oracle Database 10g: The Complete Reference , Oracle Press, ISBN 0-07-225351-7
Enlaces externos
- Descripciones del repositorio de patrones de Portland
- Guía de referencia de Berkeley DB: Operaciones con cursores
- Cursores de PostgreSQL
- Documentación sobre cursores de MySQL
- Documentación de cursores de FirebirdSQL
- Sistemas de gestión de bases de datos
- SQL
- Iteración en programación