Cursor (bases de datos)

format_list_bulleted Contenido keyboard_arrow_down
ImprimirCitar

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 posterior junto con el recorrido, como la recuperación, adición y eliminación de registros de la base de datos. La característica del cursor de la base de datos del recorrido hace que los cursores sean similares al concepto de iterador del lenguaje de programación.

Los programadores de bases de datos utilizan los cursores para procesar filas individuales devueltas por las consultas del sistema de bases de datos. Los cursores permiten la manipulación de conjuntos de resultados completos a la vez. En este escenario, un cursor permite el procesamiento secuencial de filas en un conjunto de resultados.

En los procedimientos SQL, un cursor permite definir un conjunto de resultados (un conjunto de filas de datos) y realizar una lógica compleja fila por fila. Al utilizar la misma mecánica, un procedimiento SQL también puede definir un conjunto de resultados y devolverlo directamente a la persona que llama al procedimiento SQL o a una aplicación cliente.

Un cursor puede verse como un puntero a una fila en 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:

  1. Declarar un cursor que define un conjunto de resultados
  2. Abra el cursor para establecer el conjunto de resultados
  3. Obtenga los datos en variables locales según sea necesario desde el cursor, una fila a la vez
  4. Cerrar el cursor cuando se hace

Para trabajar con cursores debe utilizar las siguientes sentencias SQL

Esta sección presenta las formas en que el estándar SQL:2003 define cómo usar cursores en aplicaciones en SQL incorporado. No todos los enlaces de aplicaciones para sistemas de bases de datos relacionales cumplen con ese estándar y algunos (como CLI o JDBC) utilizan una interfaz diferente.

Un programador hace que el DBMS conozca un cursor utilizando una instrucción DECLARE... CURSOR y asignando al cursor un nombre (obligatorio):

 DECLARE cursor_name Cursor es perfecto... De...

Antes de que el código pueda acceder a los datos, debe abrir el cursor con el OPEN declaración. Directamente después de una apertura exitosa, el cursor se coloca antes la primera fila en el conjunto de resultados.

 OPEN cursor_name

Las aplicaciones colocan los cursores en una fila específica en el conjunto de resultados con la instrucción FETCH. Una operación de recuperación transfiere los datos de la fila a la aplicación.

 FETCH cursor_name INTO...

Una vez que una aplicación ha procesado todas las filas disponibles o la operación de búsqueda debe ubicarse en una fila no existente (compare los cursores desplazables a continuación), el DBMS devuelve un SQLSTATE '02000' (normalmente acompañado de un SQLCODE +100) para indicar el final del conjunto de resultados.

El último paso implica cerrar el cursor usando la instrucción CLOSE:

 Cláusula cursor_name

Después de cerrar un cursor, un programa puede abrirlo nuevamente, lo que implica que el DBMS vuelve a evaluar la misma consulta o una consulta diferente y crea un nuevo conjunto de resultados.

Cursores desplazables

Los programadores pueden declarar 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 solo hacia adelante), puede FETCH cada fila como máximo una vez, y el cursor automáticamente pasa a la siguiente fila. Después de recuperar la última fila, si vuelve a recuperarla, colocará el cursor después de la última fila y obtendrá el siguiente código: SQLSTATE 02000 (SQLCODE +100).

Un programa puede colocar un cursor desplazable en cualquier lugar del conjunto de resultados utilizando la instrucción SQL FETCH. La palabra clave SCROLL debe especificarse al declarar el cursor. El valor predeterminado es NO SCROLL, aunque diferentes enlaces de idiomas como JDBC pueden aplicar un valor predeterminado diferente.

 DECLARE cursor_name sensibilidad SCROLL CURSOR PARA SELECT... De...

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).

 FETCH [ SIGUIENTE TENIDO PRIOR ANTE LAS PRIORAS cursor_name
 FETCH ABSOLUTE n DESDE cursor_name
 FETCH RELATIVE n DESDE cursor_name;

Los cursores escrobibles pueden acceder potencialmente a la misma fila en el resultado se establece varias veces. Así, las modificaciones de datos (insertar, actualizar, eliminar operaciones) de otras transacciones podrían afectar al conjunto de resultados. Un cursor puede ser SENSITIVO o INSENSITIVO a tales modificaciones de datos. Un cursor sensible recoge modificaciones de datos que afectan al conjunto de resultados del cursor, y un cursor insensible no lo hace. Además, un cursor puede ser INSENSITIVO, en cuyo caso el DBMS trata de aplicar la sensibilidad tanto como sea posible.

"CON RETENCIÓN"

Los cursores generalmente se cierran automáticamente al final de una transacción, es decir, cuando ocurre un COMMIT o ROLLBACK (o una terminación implícita de la transacción). Ese comportamiento se puede cambiar si el cursor se declara usando la cláusula CON HOLD (el valor predeterminado es SIN RETENCIÓN). Un cursor que se puede mantener se mantiene abierto sobre COMMIT y se cierra al ROLLBACK. (Algunos DBMS se desvían de este comportamiento estándar y también mantienen abiertos los cursores que se pueden mantener abiertos durante ROLLBACK).

 DECLARE cursor_name CURSOR CON HOLD Por supuesto... De...

Cuando ocurre un COMMIT, un cursor que se puede mantener se coloca antes de la siguiente fila. Por lo tanto, una instrucción UPDATE posicionada o DELETE posicionada solo tendrá éxito después de que se haya producido una operación FETCH primero en la transacción.

Tenga en cuenta que JDBC define los cursores como retenibles por defecto. Esto se hace porque JDBC también activa la confirmación automática de forma predeterminada.

Declaraciones de actualización/eliminación posicionadas

Los cursores no sólo se pueden utilizar para recuperar datos del DBMS en una aplicación, sino también para identificar una fila en una tabla que se actualizará o eliminará. El estándar SQL:2003 define declaraciones SQL de actualización posicionada y eliminación posicionada para ese propósito. Estas declaraciones no utilizan una cláusula WHERE normal con predicados. En cambio, un cursor identifica la fila. El cursor debe estar abierto y posicionado en una fila mediante la instrucción FETCH.

 UPDATE table_nameSET...
Donde CURRENT OF cursor_name
 DELETE
DESDE table_nameDonde CURRENT OF cursor_name

El cursor debe funcionar en un resultado actualizado con el fin de ejecutar con éxito una actualización posicionada o eliminar declaración. De lo contrario, el DBMS no sabría cómo aplicar los cambios de datos a los cuadros subyacentes mencionados en 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 es diferente de los cursores en transacciones no distribuidas.

Sin embargo, hay que prestar atención al utilizar cursores sujetables. Las conexiones pueden ser utilizadas por diferentes aplicaciones. Por lo tanto, una vez finalizada y confirmada una transacción, una transacción posterior (que se ejecuta en una aplicación diferente) podría heredar los cursores que se pueden mantener existentes. Por lo tanto, el desarrollador de aplicaciones debe ser consciente de esa situación.

Cursores en XQuery

El lenguaje XQuery permite crear cursores usando la función subsequence().

El formato es:

Deja $vista secuencia := subsequence()$resultado, $Empieza, $contable)

Donde $resultado es el resultado de la XQuery inicial, $start es el número de artículo para comenzar y $item-count es el Número de artículos a devolver.

De manera equivalente, esto también se puede hacer usando un predicado:

Deja $vista secuencia := $resultado[$Empieza a $final]

Donde $end es la secuencia final.

Para ejemplos completos ver XQuery/Searching,Paging y Sorting#Paging en Wikibooks.

Desventajas de los cursores

La siguiente información puede variar según el sistema de base de datos específico.

Obtener una fila desde el cursor puede resultar en un viaje de ida y vuelta de la red cada vez. Esto utiliza mucho más ancho de banda de red del que normalmente se necesitaría para la ejecución de una única instrucción SQL como DELETE. Los viajes repetidos de ida y vuelta a la red pueden reducir gravemente la velocidad de la operación utilizando el cursor. Algunos DBMS intentan reducir este efecto mediante el uso de búsqueda de bloques. La recuperación de 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 recupera las filas desde allí hasta que se agota ese búfer.

Los cursores asignan recursos en el servidor, como bloqueos, paquetes, procesos y almacenamiento temporal. Por ejemplo, Microsoft SQL Server implementa cursores creando una tabla temporal y completándola con el conjunto de resultados de la consulta. Si un cursor no se cierra correctamente (desasignado), 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 degradaciones y fallas en el rendimiento.

Ejemplo

TABLA DE EMPLEADOS

SQL desc EMPLOYEES_DETAILS; ¿Nombre Null? Tipo ----- --- -------------------- EMPLOYEE_ID NO NULL NUMBER(6) FIRST_NAME VARCHAR2(20) LAST_NAME NOT NULL VARCHAR2(25) EMAIL NOT NULL VARCHAR2(30) PHONE_NUMBER VARCHAR2(20) HIRE_DATE NOT NULL DATE JOB_ID NOT NULL VARCHAR2(10) NÚMERO SALARIO (8,2) COMMISSION_PCT NUMBER(2,2) MANAGER_ID NUMBER(6) DEPARTMENT_ID NUMBER(4)
SAMPLE CURSOR CONOCIDO ASÍ EECREATE O REPLACE PROCEDURE EE ASÍBEGINDECLAREv_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 ESSELECT EMPLOYEE_ID, FIRST_NAME, LAST_NAMEDESDE EMPLOYEES_DETAILSDonde JOB_ID ='v_JOB_ID ';BEGINOPEN c_EMPLOYEES_DETAILS;LOOPFETCH c_EMPLOYEES_DETAILS INTO v_employeeID,v_FirstName,v_LASTName;DBMS_OUTPUT.put_line()v_employeeID);DBMS_OUTPUT.put_line()v_FirstName);DBMS_OUTPUT.put_line()v_LASTName);EXIT CUANDO c_EMPLOYEES_DETAILS%NOTFOUND;FIN LOOP;Cláusula c_EMPLOYEES_DETAILS;FIN;FIN;
Más resultados...
Tamaño del texto:
undoredo
format_boldformat_italicformat_underlinedstrikethrough_ssuperscriptsubscriptlink
save