Define un nuevo cursor. Utilice un cursor para recuperar algunas filas a la vez del conjunto de resultados de una consulta más grande.
Cuando se recupera la primera fila de un cursor, el conjunto completo de resultados se materializa en el nodo principal, en la memoria o en el disco, si es necesario. Debido al posible impacto negativo en el rendimiento del uso de cursores con conjuntos de resultados grandes, recomendamos usar enfoques alternativos cuando sea posible. Para obtener más información, consulte Consideraciones acerca del rendimiento cuando se utilizan cursores.
Debe declarar un cursor dentro de un bloque de transacción. Solo se puede abrir un cursor a la vez por sesión.
Para obtener más información, consulte FETCH, CLOSE.
Sintaxis
DECLARE cursor_name CURSOR FOR query
Parámetros
- cursor_name
-
Nombre del nuevo cursor.
- consulta
-
Una instrucción SELECT que rellena el cursor.
Notas de uso acerca de DECLARE CURSOR
Si su aplicación cliente utiliza una conexión Open Database Connectivity (ODBC, Conectividad de base de datos abierta) y su consulta crea un conjunto de resultados que es demasiado grande para entrar en la memoria, puede transmitir el conjunto de resultados a su aplicación cliente por medio del cursor. Cuando utiliza un cursor, el conjunto completo de resultados se materializa en el nodo principal y, luego, el cliente puede recuperar los resultados gradualmente.
nota
Para habilitar cursores en ODBC para Microsoft Windows, habilite la opción Use Declare/Fetch (Utilizar Declarar/Recuperar) en el nombre de origen de datos (DSN) de ODBC que utiliza para Amazon Redshift. En los clústeres de varios nodos, es recomendable establecer el tamaño de la caché de ODBC en 4000 o un valor superior utilizando el campo Cache Size (Tamaño de caché) del cuadro de diálogo de opciones del DSN de ODBC para minimizar los recorridos de ida y vuelta. En un clúster de un nodo, configure el tamaño de la caché en 1 000.
Debido al posible impacto negativo en el rendimiento del uso de cursores, recomendamos usar enfoques alternativos cuando sea posible. Para obtener más información, consulte Consideraciones acerca del rendimiento cuando se utilizan cursores.
Los cursores de Amazon Redshift se admiten con las siguientes limitaciones:
-
Solo se puede abrir un cursor a la vez por sesión.
-
Los cursores deben utilizarse dentro de una transacción (BEGIN … END).
-
El tamaño máximo del conjunto de resultados acumulables para todos los cursores está limitado en función del tipo de nodo del clúster. Si necesita conjuntos de resultados más grandes, puede cambiar el tamaño a una configuración de nodos XL o 8XL.
Para obtener más información, consulte Restricciones del cursor.
Restricciones del cursor
Cuando se recupera la primera fila de un cursor, el conjunto completo de resultados se materializa en el nodo principal. Si el conjunto de resultados no entra en la memoria, se escribe en el disco, según sea necesario. Para proteger la integridad del nodo principal, Amazon Redshift aplica restricciones al tamaño de todos los conjuntos de resultados del cursor, en función del tipo de nodo del clúster.
En la tabla siguiente se muestra el tamaño máximo total del conjunto de resultados para cada tipo de nodo de clúster. Los tamaños máximos del conjunto de resultados se expresan en megabytes.
Tipo de nodo | Conjunto de resultados máximo por clúster (MB) |
---|---|
Varios nodos DC2 Large |
192 000 |
Un solo nodo DC2 Large |
8000 |
Varios nodos DC2 8XL |
3 200 000 |
Varios nodos RA3 16XL |
14 400 000 |
Varios nodos RA3 4XL |
3 200 000 |
Varios nodos RA3 XLPLUS |
1 000 000 |
Nodo único RA3 XLPLUS |
64 000 |
Varios nodos RA3 LARGE |
240 000 |
Un nodo RA3 LARGE |
8000 |
Amazon Redshift sin servidor |
150 000 |
Para ver la configuración del cursor activo para un clúster, consulte la tabla del sistema STV_CURSOR_CONFIGURATION como superusuario. Para ver el estado de los cursores activos, consulte la table del sistema STV_ACTIVE_CURSORS. El usuario puede ver solo las filas de los propios cursores de un usuario, pero un superusuario puede ver todos los cursores.
Consideraciones acerca del rendimiento cuando se utilizan cursores
Debido a que los cursores materializan el conjunto completo de resultados en el nodo principal antes de comenzar a devolver resultados al cliente, el uso de cursores con conjuntos de resultados grandes puede tener un impacto negativo en el rendimiento. No recomendamos utilizar cursores con conjuntos de resultados muy grandes. En algunos casos, como cuando la aplicación usa una conexión ODBC, los cursores pueden ser la única solución viable. Si es posible, recomendamos utilizar estas alternativas:
-
Utilice UNLOAD para exportar una tabla grande. Cuando utiliza UNLOAD, los nodos informáticos trabajan en paralelo para transferir los datos de forma directa a los archivos de datos en Amazon Simple Storage Service. Para obtener más información, consulte Descarga de datos en Amazon Redshift.
-
Establezca el parámetro de búsqueda de JDBC en la aplicación cliente. Si utiliza una conexión JDBC y se encuentra con errores de falta de memoria del lado del cliente, puede habilitar el cliente para recuperar conjuntos de resultados en lotes más pequeños al configurar el parámetro de tamaño de búsqueda de JDBC. Para obtener más información, consulte Configuración del parámetro de tamaño de búsqueda de la JDBC.
Ejemplos de DECLARE CURSOR
En el siguiente ejemplo, se declara un cursor denominado LOLLAPALOOZA para seleccionar información de ventas para el evento Lollapalooza y, luego, se recuperan filas del conjunto de resultados a través del cursor:
-- Begin a transaction
begin;
-- Declare a cursor
declare lollapalooza cursor for
select eventname, starttime, pricepaid/qtysold as costperticket, qtysold
from sales, event
where sales.eventid = event.eventid
and eventname='Lollapalooza';
-- Fetch the first 5 rows in the cursor lollapalooza:
fetch forward 5 from lollapalooza;
eventname | starttime | costperticket | qtysold
--------------+---------------------+---------------+---------
Lollapalooza | 2008-05-01 19:00:00 | 92.00000000 | 3
Lollapalooza | 2008-11-15 15:00:00 | 222.00000000 | 2
Lollapalooza | 2008-04-17 15:00:00 | 239.00000000 | 3
Lollapalooza | 2008-04-17 15:00:00 | 239.00000000 | 4
Lollapalooza | 2008-04-17 15:00:00 | 239.00000000 | 1
(5 rows)
-- Fetch the next row:
fetch next from lollapalooza;
eventname | starttime | costperticket | qtysold
--------------+---------------------+---------------+---------
Lollapalooza | 2008-10-06 14:00:00 | 114.00000000 | 2
-- Close the cursor and end the transaction:
close lollapalooza;
commit;
El siguiente ejemplo realiza un bucle en un refcursor con todos los resultados de una tabla:
CREATE TABLE tbl_1 (a int, b int);
INSERT INTO tbl_1 values (1, 2),(3, 4);
CREATE OR REPLACE PROCEDURE sp_cursor_loop() AS $$
DECLARE
target record;
curs1 cursor for select * from tbl_1;
BEGIN
OPEN curs1;
LOOP
fetch curs1 into target;
exit when not found;
RAISE INFO 'a %', target.a;
END LOOP;
CLOSE curs1;
END;
$$ LANGUAGE plpgsql;
CALL sp_cursor_loop();
SELECT message
from svl_stored_proc_messages
where querytxt like 'CALL sp_cursor_loop()%';
message
----------
a 1
a 3