¿Qué es un fetch en base de datos?

FETCH en Bases de Datos: Recuperando Filas

★★★★★Valoración: 4.65 (7754 votos)

Cuando trabajas con bases de datos y ejecutas una consulta que devuelve múltiples filas, a menudo necesitas procesar esos resultados de manera programática, es decir, dentro de un bloque de código como un procedimiento almacenado o una función. Aquí es donde entra en juego el concepto de FETCH.

¿Qué es fetch?
Fetch es una aplicación gratuita de recompensas que permite a los usuarios comprar en línea, escanear recibos y jugar juegos móviles para ganar puntos . Una vez que acumulen suficientes puntos, podrán canjearlos por tarjetas de regalo.

A diferencia de una simple instrucción SELECT que devuelve un conjunto de resultados (result set), la sentencia FETCH se utiliza en conjunción con un mecanismo llamado cursor para recuperar esas filas una a una o en grupos, permitiéndote trabajar con cada registro individualmente o en lotes dentro de tu lógica de programación.

Índice de Contenido

¿Qué es un Cursor y Por Qué lo Necesitas?

Antes de sumergirnos en FETCH, es fundamental entender el papel de un cursor. Piensa en un cursor como un puntero o un identificador a un área de memoria en el servidor de la base de datos donde se almacena el conjunto de resultados de una consulta. Un cursor te permite:

  • Ejecutar una consulta (abrir el cursor).
  • Navegar a través del conjunto de resultados.
  • Recuperar filas del conjunto de resultados (usando FETCH).
  • Saber cuándo has llegado al final del conjunto de resultados.
  • Liberar los recursos asociados al conjunto de resultados (cerrar el cursor).

Sin un cursor, sería difícil procesar un conjunto de resultados grande fila por fila dentro de un lenguaje de programación procedural como PL/SQL (usado en Oracle Database) o T-SQL (usado en SQL Server), que son entornos donde la sentencia FETCH es comúnmente encontrada.

La Sentencia FETCH: Recuperando Datos del Cursor

La sentencia FETCH es el comando que utilizas para extraer datos del conjunto de resultados asociado a un cursor que previamente has abierto. La sintaxis básica implica especificar el cursor del que quieres recuperar datos y las variables o estructuras donde quieres almacenar la información de la fila actual.

FETCH Fila a Fila

La forma más simple de usar FETCH es para recuperar una sola fila cada vez que ejecutas la sentencia. Esto se hace típicamente dentro de un bucle (LOOP) que continúa hasta que no hay más filas que recuperar.

¿Qué es un método fetch?
El método fetch() lanza el proceso de solicitud de un recurso de la red. Esto devuelve una promesa que resuelve al objeto Response que representa la respuesta a la solicitud realizada.
DECLARE mi_salario NUMBER(7,2); nombre_empleado VARCHAR2(100); CURSOR emp_cursor IS SELECT ename, sal FROM emp WHERE job = 'CLERK';BEGIN OPEN emp_cursor; -- Abre el cursor para ejecutar la consulta LOOP FETCH emp_cursor INTO nombre_empleado, mi_salario; -- Recupera la siguiente fila EXIT WHEN emp_cursor%NOTFOUND; -- Sale del bucle si no hay más filas -- Aquí procesas la fila recuperada (nombre_empleado, mi_salario) DBMS_OUTPUT.PUT_LINE('Empleado: ' || nombre_empleado || ', Salario: ' || mi_salario); END LOOP; CLOSE emp_cursor; -- Cierra el cursor para liberar recursosEND;

En este ejemplo, FETCH emp_cursor INTO nombre_empleado, mi_salario; recupera los valores de las columnas ename y sal de la fila actual del cursor emp_cursor y los asigna a las variables nombre_empleado y mi_salario, respectivamente. Cada vez que se ejecuta FETCH, el cursor avanza a la siguiente fila.

La Cláusula INTO

La cláusula INTO es esencial en la sentencia FETCH. Especifica las variables, campos de registro o elementos de colección donde se almacenarán los datos recuperados de las columnas de la fila actual del cursor. Es crucial que el número y tipo de datos de las variables en la cláusula INTO coincidan con el número y tipo de datos de las columnas seleccionadas en la consulta del cursor.

Uso con Registros (%ROWTYPE)

En lugar de declarar múltiples variables individuales, puedes declarar un registro (record) basado en la estructura de una tabla o en el tipo de fila del cursor (usando %ROWTYPE). Esto simplifica el código cuando la consulta selecciona muchas columnas.

DECLARE TYPE EmpCurTyp IS REF CURSOR RETURN emp%ROWTYPE; -- Tipo de cursor variable emp_cv EmpCurTyp; -- Variable de cursor emp_rec emp%ROWTYPE; -- Registro basado en la estructura de la tabla empBEGIN -- Asumimos que emp_cv ya está abierto y asociado a una consulta LOOP FETCH emp_cv INTO emp_rec; -- Recupera la fila en el registro EXIT WHEN emp_cv%NOTFOUND; -- Procesar emp_rec.ename, emp_rec.sal, etc. DBMS_OUTPUT.PUT_LINE('Empleado: ' || emp_rec.ename || ', Trabajo: ' || emp_rec.job); END LOOP; -- Si el cursor variable se abrió aquí, se cerraría aquíEND;

BULK COLLECT para Rendimiento

Recuperar filas una a una con FETCH dentro de un bucle procedural puede ser ineficiente para conjuntos de resultados grandes debido al constante cambio de contexto entre el motor SQL y el motor procedural (como PL/SQL). Para mejorar el rendimiento, especialmente al tratar con muchas filas, se utiliza la cláusula BULK COLLECT.

BULK COLLECT permite a la sentencia FETCH recuperar múltiples filas a la vez en colecciones (como arrays o tablas anidadas) en una sola operación. Esto reduce significativamente el número de viajes de ida y vuelta entre los motores SQL y procedural.

¿Qué es fetch en una base de datos?
La instrucción FETCH recupera filas de datos del conjunto de resultados de una consulta multifila . Puede recuperar filas de una en una, varias a la vez o todas a la vez. Los datos se almacenan en variables o campos que corresponden a las columnas seleccionadas por la consulta. Para más información, consulte "Consultas de datos con PL/SQL".
DECLARE TYPE NameList IS TABLE OF emp.ename%TYPE; TYPE SalList IS TABLE OF emp.sal%TYPE; nombres NameList; salarios SalList; CURSOR c1 IS SELECT ename, sal FROM emp WHERE job = 'SALESMAN';BEGIN OPEN c1; -- BULK COLLECT recupera todas las filas (o hasta el límite) en las colecciones FETCH c1 BULK COLLECT INTO nombres, salarios; -- Ahora puedes iterar sobre las colecciones nombres y salarios FOR i IN 1..nombres.COUNT LOOP DBMS_OUTPUT.PUT_LINE('Vendedor: ' || nombres(i) || ', Salario: ' || salarios(i)); END LOOP; CLOSE c1;END;

La Cláusula LIMIT con BULK COLLECT

Para evitar cargar un número excesivo de filas en memoria a la vez (lo cual podría causar errores de memoria para conjuntos de resultados gigantes), puedes combinar BULK COLLECT con la cláusula LIMIT. Esto te permite recuperar filas en lotes de un tamaño especificado.

DECLARE TYPE NumList IS TABLE OF NUMBER INDEX BY BINARY_INTEGER; CURSOR c1 IS SELECT acct_id FROM accounts; acct_ids NumList; batch_size CONSTANT NATURAL := 100; -- Define el tamaño del loteBEGIN OPEN c1; LOOP -- Recupera hasta 'batch_size' filas en la colección FETCH c1 BULK COLLECT INTO acct_ids LIMIT batch_size; -- Procesar el lote de IDs recuperados en acct_ids -- ... tu lógica de procesamiento aquí ... -- Salir del bucle cuando el último FETCH no recuperó filas EXIT WHEN c1%NOTFOUND; END LOOP; CLOSE c1;END;

Manejo de Errores y Atributos del Cursor

Es crucial saber cómo verificar el estado de una operación FETCH y manejar posibles situaciones.

  • %NOTFOUND: Este atributo de cursor devuelve TRUE si el último FETCH no devolvió ninguna fila. Es la forma estándar de detectar el final del conjunto de resultados y salir de un bucle de FETCH.
  • %FOUND: Lo opuesto a %NOTFOUND, devuelve TRUE si el último FETCH devolvió al menos una fila.
  • INVALID_CURSOR: Esta excepción predefinida se lanza si intentas hacer FETCH desde un cursor que está cerrado o que nunca fue abierto.

Es importante notar que hacer FETCH más allá de la última fila *no* lanza una excepción; simplemente las variables de destino quedan en un estado indeterminado y %NOTFOUND se vuelve TRUE. Debes usar %NOTFOUND para controlar tu bucle.

Consideraciones Importantes

  • Las variables utilizadas en la cláusula WHERE de la consulta de un cursor se evalúan solo una vez, cuando el cursor se abre. Si necesitas cambiar los valores de esas variables y obtener un conjunto de resultados diferente, debes cerrar y volver a abrir el cursor (para cursores explícitos) o simplemente reabrirlo (para variables de cursor) con los nuevos valores de las variables.
  • Puedes usar diferentes listas INTO en distintas operaciones FETCH sobre el mismo cursor o variable de cursor. Cada FETCH recuperará la siguiente fila y asignará valores a las variables objetivo correspondientes.
  • Cuando declaras una variable de cursor como parámetro formal de una subrutina que hará FETCH desde ella, debes especificar el modo IN o IN OUT. Si la subrutina también abre la variable de cursor, debe ser IN OUT.

Tabla Comparativa: FETCH Fila a Fila vs. BULK COLLECT

CaracterísticaFETCH Fila a FilaFETCH BULK COLLECT
GranularidadUna fila por operaciónMúltiples filas por operación (en lotes)
Destino de DatosVariables o registros escalaresColecciones (arrays, tablas anidadas)
Rendimiento (Muchas Filas)Menos eficiente (alto overhead de contexto)Más eficiente (reduce overhead de contexto)
Uso de MemoriaBajo (procesa una fila a la vez)Puede ser alto (carga múltiples filas en memoria), mitigado por LIMIT
Complejidad del CódigoGeneralmente más simple para lógica fila a filaRequiere manejo de colecciones
Ideal ParaProcesamiento lógico complejo por fila, conjuntos de resultados pequeñosProcesamiento que opera sobre conjuntos de datos, ETL, conjuntos de resultados grandes

Preguntas Frecuentes sobre FETCH en Bases de Datos

¿Es FETCH lo mismo que SELECT?

No. SELECT define y recupera un conjunto de resultados. FETCH es una sentencia procedural que recupera filas de un conjunto de resultados que ya ha sido generado por una consulta (generalmente asociado a un cursor).

¿Qué pasa si hago FETCH cuando no quedan filas?

La sentencia FETCH se ejecuta, pero no asigna valores a las variables de destino (su estado es indeterminado) y el atributo %NOTFOUND del cursor asociado se vuelve TRUE. No se lanza una excepción por sí sola.

¿Puedo usar JavaScript para conectarme a una base de datos?
Sí, JavaScript puede acceder a una base de datos SQL a través de marcos del lado del servidor como Node. js , utilizando bibliotecas como mysql o pg (para PostgreSQL).

¿Por qué usar BULK COLLECT en lugar de FETCH normal?

Para mejorar el rendimiento al recuperar y procesar un gran número de filas. Reduce el número de interacciones entre el motor SQL y el motor procedural, lo que disminuye el overhead.

¿Puedo usar FETCH sin un cursor?

En la mayoría de los contextos donde se usa la sentencia FETCH como tal (como PL/SQL), no. FETCH opera sobre un cursor previamente abierto que apunta a un conjunto de resultados.

¿Cuándo se evalúan las variables en la cláusula WHERE de un cursor?

Las variables en la cláusula WHERE de la consulta de un cursor se evalúan en el momento en que se ejecuta la sentencia OPEN para ese cursor.

En resumen, la sentencia FETCH es una herramienta poderosa y necesaria para interactuar programáticamente con los conjuntos de resultados de tus consultas en bases de datos. Ya sea recuperando datos fila a fila para una lógica detallada o utilizando BULK COLLECT para optimizar el rendimiento con grandes volúmenes de datos, comprender y aplicar FETCH correctamente es fundamental para el desarrollo eficiente de aplicaciones de base de datos.

Si quieres conocer otros artículos parecidos a FETCH en Bases de Datos: Recuperando Filas puedes visitar la categoría Bases de datos.

Ivan

Soy un entusiasta de la tecnología con especialización en bases de datos, particularmente en MySQL. A través de mis tutoriales detallados, busco desmitificar los conceptos complejos y proporcionar soluciones prácticas a los desafíos cotidianos relacionados con la gestión de datos

Aprende mas sobre MySQL

Subir