sql >> Base de Datos >  >> RDS >> Mysql

Trabajar con cursores SQL

En SQL, los cursores sirven como un puntero que permite que el lenguaje de programación de aplicaciones se ocupe de los resultados de la consulta una fila a la vez. Este artículo explora rápidamente el concepto subyacente y muestra cómo declarar cursores, abrirlos, recuperar datos de ellos y luego cerrarlos.

Cursores SQL

Los datos en la base de datos relacional se gestionan en forma de conjuntos. Como resultado, los resultados de la consulta que devuelven las sentencias SQL SELECT se conocen como conjuntos de resultados. Los conjuntos de resultados no son más que combinaciones de una o más filas y columnas extraídas de una o más tablas. Puede desplazarse por los conjuntos de resultados para extraer la información que necesita. Los elementos de datos devueltos son utilizados por lenguajes de programación como Java o cualquier otro para fines de aplicaciones específicas. Pero aquí radica el problema del desajuste de impedancia debido a la diferencia de construcción entre el modelo de base de datos y el modelo de lenguaje de programación.

Un modelo de base de datos SQL tiene tres construcciones principales:

  • columnas (o atributos) y sus tipos de datos
  • filas (registros o tuplas)
  • tablas (colección de registros)

Por lo tanto, los principales desajustes entre dos modelos son:

  1. Los tipos de datos de atributos disponibles en el modelo de base de datos no son los mismos que los tipos de variables que se usan en los lenguajes de programación. Hay muchos lenguajes anfitriones y cada uno tiene un tipo de datos diferente. Por ejemplo, los tipos de datos de C/C++ y Java son diferentes, al igual que los tipos de datos de SQL. Por lo tanto, es necesario un mecanismo vinculante para mitigar el problema de incompatibilidad.
  2. El resultado devuelto por las instrucciones SQL SELECT son conjuntos múltiples de registros donde cada registro es una colección de atributos. Los lenguajes de programación host generalmente funcionan en valores de datos individuales de tupla devueltos por la consulta. Por lo tanto, es esencial que el resultado de la consulta SQL se corresponda con la estructura de datos admitida por el lenguaje de programación. El mecanismo de bucle sobre tuplas es necesario para iterar sobre tuplas y sus valores de atributo.

El cursor actúa como una variable iteradora para recorrer las tuplas devueltas por la consulta SQL y extraer valores individuales dentro de cada tupla que luego se pueden asignar al tipo apropiado de variables de programa.

El cursor, por lo tanto, sirve como un puntero que permite que el lenguaje de programación procese el resultado de la consulta un registro a la vez. Un cursor puede recorrer todas las filas de un resultado de consulta centrándose en una fila a la vez. Considere la siguiente consulta SQL:

SELECT emp_no, first_name, last_name, birth_date
FROM employees
WHERE MONTH(birth_date) = MONTH(CURRENT_DATE)
AND DAY(birth_date) = DAY(CURRENT_DATE);

El resultado de la consulta de la declaración anterior devuelve los detalles de los empleados de todos aquellos empleados cuya fecha de nacimiento cae en el día actual de un mes en particular. El resultado puede contener muchas filas, pero el idioma de la aplicación host puede manejar una fila a la vez. Como resultado, el cursor se declara como una instrucción SQL incrustada dentro del lenguaje de programación de la aplicación. Luego, el cursor se abre como un archivo y extrae una sola fila del resultado de la consulta. Otras filas se extraen posteriormente, en secuencia hasta que se cierra el cursor.

Declaración de un cursor

Los cursores se declaran como una variable. Se da un nombre, hay declaraciones para abrir el cursor, recuperar el resultado de la consulta y finalmente cerrar el cursor. Tenga en cuenta que las diferentes implementaciones de SQL admiten el uso de cursores de forma diferente. Pero hay un acuerdo general sobre cómo se debe escribir el cursor.

Debemos usar declaraciones SQL para implementar completamente la funcionalidad del cursor porque simplemente declarar un cursor no es suficiente para extraer datos de una base de datos SQL. Hay cuatro pasos básicos para declarar un cursor:

DECLARACIÓN DEL CURSOR: La declaración comienza dando un nombre al cursor y asignando la expresión de consulta que se invocará cuando se abra el cursor.

ABRIR: La declaración abierta ejecuta la expresión de consulta asignada y prepara el resultado de la consulta para FETCH subsiguiente.

BUSCAR: Recupera valores de datos en variables que luego se pueden pasar al lenguaje de programación host o a otras declaraciones SQL integradas.

CERRAR: El cursor no puede obtener más resultados de consulta.

La sintaxis es la siguiente:

DECLARE <cursor_name>
[SENSITIVE | INSENSITIVE | ASENSITIVE]
[SCROLL | NO SCROLL] CURSOR
[ WITH HOLD | WITHOUT HOLD]
[ WITH RETURN | WITHOUT RETURN]
FOR <sql_query_expression>
[ ORDER BY <sort_expression>]
[ FOR {READ ONLY | UPDATE [ OF <list_of_column>]}]

La parte esencial de una declaración de cursor es la siguiente:

 DECLARE <cursor_name> FOR <sql_query_expression>

La parte opcional como [SENSITIVE | INSENSIBLE | ASENSITIVE] significa si el cursor es sensible a los cambios y si los reflejará en el resultado de la consulta. SENSIBLE significa que el cursor se ve afectado por los cambios, INSENSITIVO significa que el cursor no se ve afectado y ASENSITIVO significa que los cambios pueden o no ser visibles para el cursor. Si no se especifica asume la opción SENSIBLE.

El [DESPLAZAMIENTO | NOSCROLL] define la capacidad de desplazamiento del cursor. Si no se especifica, asume la opción SIN DESPLAZAMIENTO.

El [ CON HOLD | SIN RETENCIÓN] define si retener o cerrar automáticamente cuando se confirma la transacción debida al cursor. Si no se especifica mantiene la opción SIN RETENCIÓN.

El opcional [ CON RETORNO | SIN RETORNO] determina si devolver el conjunto de resultados del cursor al invocador, como otra rutina de SQL o lenguaje principal. Si no se especifica significa SIN DEVOLUCIÓN.

La cláusula ORDER BY se utiliza para clasificar el resultado de la consulta de acuerdo con la técnica de clasificación especificada.

La opción UPDATE se refiere al uso de la instrucción UPDATE o DELETE en asociación con las filas devueltas por la instrucción SELECT del cursor. Cualquier modificación de este tipo no es posible si especificamos la opción SÓLO LECTURA. Si no se especifica, se asume por defecto la opción ACTUALIZAR.

Por lo tanto, un cursor simple se puede declarar de la siguiente manera:

DECLARE mycursor CURSOR
 FOR
SELECT emp_no, first_name, last_name, birth_date
  FROM employees
 WHERE MONTH(birth_date) = MONTH(CURRENT_DATE)
  AND DAY(birth_date) = DAY(CURRENT_DATE);

Cursores en MySQL

Por lo general, hay dos tipos de cursores que se encuentran en MySQL:cursores de solo lectura y de solo avance. Estos cursores se pueden usar para el procedimiento almacenado de MySQL. Estos cursores nos ayudan a iterar sobre los resultados de la consulta una fila a la vez y obtener variables para su posterior procesamiento. Es posible declarar más de un cursor y anidarlos en bucles. Tenga en cuenta que los cursores son de solo lectura porque se utilizan para iterar sobre tablas temporales. El cursor normalmente ejecuta la consulta cuando la abrimos.

Uno de los problemas con el cursor en MySQL es que pueden ralentizar el rendimiento de la consulta debido a las operaciones de E/S adicionales que realizan. Esto es particularmente para verdaderos tipos de datos grandes como BLOB y TEXT. Como los cursores funcionan con tablas temporales, estos tipos no se admiten en las tablas en memoria. Por lo tanto, mientras trabaja con estos tipos, MySQL tiene que crear tablas temporales en el disco y eso requiere mucha operación de E/S y eso también en dispositivos lentos como los discos. Esta es la razón principal del lento rendimiento del cursor.

MySQL tampoco admite cursores del lado del cliente; sin embargo, la API del cliente puede emularlos si es necesario. Pero esto no es muy diferente de obtener el resultado en una matriz en un lenguaje de programación como Java y manipularlos allí en su lugar.

Aquí hay una muestra de cómo escribir cursores en MySQL.

CREATE PROCEDURE 'cursor_demo'()
BEGIN
    DECLARE done INT DEFAULT FALSE;
    DECLARE id INT(11);
    DECLARE fn varchar(14);
    DECLARE ln varchar(16);
    DECLARE bdate date;
  DECLARE mycursor CURSOR FOR
  SELECT emp_no, first_name, last_name, birth_date
    FROM employees
    WHERE MONTH(birth_date)=MONTH(CURRENT_DATE)
      AND DAY(birth_date)=DAY(CURRENT_DATE);
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    OPEN mycursor;
  fetch_loop: LOOP
    FETCH mycursor INTO id, fn, ln, bdate;
  IF done THEN
      LEAVE fetch_loop;
    END IF;
    SELECT id, fn, ln, bdate;
  END LOOP;
  CLOSE mycursor;
END

Llame al procedimiento almacenado de la siguiente manera:

mysql> CALL cursor_demo

El procedimiento obtiene las filas de una tabla denominada empleado cuya fecha de nacimiento coincida con el día y el mes actuales en un cursor llamado mycursor y simplemente los imprime usando la instrucción SELECT.

Consulte la documentación de MySQL sobre el cursor para obtener más información.

Conclusión

Los cursores no son más que punteros a los conjuntos de registros devueltos por la consulta SQL. El puntero generalmente apunta a una fila a la vez y se puede recorrer en un bucle para recuperar registros individuales. SQL se usa normalmente para la invocación directa para acceder y crear objetos de datos. Los cursores proporcionan la técnica de SQL interactivo donde permite la ejecución ad hoc de sentencias SQL facilitadas a través de la aplicación del cliente. El mecanismo del cursor aprovecha el modelo de acceso a datos en el que las sentencias SQL están integradas en el lenguaje anfitrión, como C, C++ o Java, etc. Esto es solo un vistazo de lo que es el cursor para empezar. Consulte la documentación de la base de datos SQL correspondiente para obtener detalles sobre las normas específicas de varias implementaciones.

###