openGauss Cursors
To process SQL statements, the stored procedure process assigns a memory segment to store context association. Cursors are handles or pointers pointing to context regions. With cursors, stored procedures can control alterations in context regions.
Syntax
Define a cursor.
CURSOR cursor_name [ BINARY ] [ NO SCROLL ] [ { WITH | WITHOUT } HOLD ] FOR query ;
Retrieve data by using a created cursor.
FETCH [ direction { FROM | IN } ] cursor_name;
The direction clause specifies optional parameters.
NEXT | PRIOR | FIRST | LAST | ABSOLUTE count | RELATIVE count | count | ALL | FORWARD | FORWARD count | FORWARD ALL | BACKWARD | BACKWARD count | BACKWARD ALL
Reposition a cursor without retrieving any data.
The MOVE statement works exactly like the FETCH statement, except that it only repositions the cursor and does not return rows.
MOVE [ direction [ FROM | IN ] ] cursor_name;
The direction clause specifies optional parameters.
NEXT | PRIOR | FIRST | LAST | ABSOLUTE count | RELATIVE count | count | ALL | FORWARD | FORWARD count | FORWARD ALL | BACKWARD | BACKWARD count | BACKWARD ALL
Close a cursor and release all resources associated with the cursor.
CLOSE { cursor_name | ALL } ;
Parameter Description
cursor_name
Specifies the name of the cursor to be created or closed.
BINARY
Specifies that data retrieved by a cursor will be returned in binary format, not in text format.
NO SCROLL
Specifies how a cursor retrieves rows.
NO SCROLL: specifies that the cursor cannot be used to retrieve rows in a nonsequential fashion.
Unspecified: Based on the query's execution plan, the system automatically determines whether the cursor can be used to retrieve rows in a nonsequential fashion.
WITH HOLD | WITHOUT HOLD
Specifies whether a cursor can be used after the transaction that created it ends.
WITH HOLD: The cursor can be used after the transaction that created it ends.
WITHOUT HOLD: The cursor cannot be used outside of the transaction that created it.
If neither WITH HOLD nor WITHOUT HOLD is specified, the default is WITHOUT HOLD.
Cross-node transactions (for example, DDL-contained transactions created in openGauss with multiple DBnode) do not support WITH HOLD.
query
Uses the SELECT or VALUES clause to specify the rows to be returned by a cursor.
Value range: SELECT or VALUES clause
direction_clause
Defines the fetch direction.
Value range:
NEXT (default value)
Fetches the next row.
PRIOR
Fetches the prior row.
FIRST
Fetches the first row of the query (same as ABSOLUTE 1).
LAST
Fetches the last row of the query (same as ABSOLUTE – 1).
ABSOLUTE count
Fetches the countth row of the query.
ABSOLUTE fetches are not any faster than navigating to the desired row with a relative move, because the underlying implementation must traverse all the intermediate rows anyway.
Value range: a possibly-signed integer
If count is positive, the countth row of the query will be fetched.
If count is negative, the abs(count)th row from the end of the query result will be fetched.
If count is set to 0, the cursor is positioned before the first row.
RELATIVE count
Fetches the countth succeeding row or the countth prior row.
Value range: a possibly-signed integer
If count is positive, the countth succeeding rows will be fetched.
If count is negative, the abs(count)th prior rows will be fetched.
If the current row contains no data, RELATIVE 0 returns NULL.
count
Fetches the next count rows (same as FORWARD count).
ALL
Fetches all remaining rows (same as FORWARD ALL).
FORWARD
Fetches the next row (same as NEXT).
FORWARD count
Fetches the count succeeding rows or count prior rows.
FORWARD ALL
Fetches all remaining rows.
BACKWARD
Fetches the prior row (same as PRIOR).
BACKWARD count
Fetches the prior count rows (scanning backwards).
Value range: a possibly-signed integer
If count is positive, the prior count rows will be fetched.
If count is a negative, the succeeding abs (count) rows will be fetched.
BACKWARD 0 re-fetches the current row, if any.
BACKWARD ALL
Fetches all prior rows (scanning backwards).
{ FROM | IN } cursor_name
Specifies the cursor name using the keyword FROM or IN.
Value range: an existing cursor name
ALL
Closes all open cursors.
Examples
Assume that the customer_t1 table exists and contains the following data:
openGauss=# SELECT * FROM customer_t1;
c_customer_sk | c_customer_id | c_first_name | c_last_name | amount
---------------+---------------+--------------+-------------+--------
3769 | | Grace | |
3769 | hello | | |
6885 | maps | Joes | | 2200
4321 | tpcds | Lily | | 3000
9527 | world | James | | 5000
(5 rows)
Read a table using a cursor.
-- Start a transaction. openGauss=# START TRANSACTION; START TRANSACTION -- Set up cursor1. openGauss=# CURSOR cursor1 FOR SELECT * FROM customer_t1; DECLARE CURSOR -- Fetch the first three rows in cursor1. openGauss=# FETCH FORWARD 3 FROM cursor1; c_customer_sk | c_customer_id | c_first_name | c_last_name | amount ---------------+---------------+--------------+-------------+-------- 3769 | | Grace | | 3769 | hello | | | 6885 | maps | Joes | | 2200 (3 rows) -- Close the cursor and commit the transaction. openGauss=# CLOSE cursor1; CLOSE CURSOR -- End the transaction. openGauss=# END; COMMIT
Read the VALUES clause using a cursor.
-- Start a transaction. openGauss=# START TRANSACTION; START TRANSACTION -- Set up cursor2. openGauss=# CURSOR cursor2 FOR VALUES(1,2),(0,3) ORDER BY 1; DECLARE CURSOR -- Fetch the first two rows in cursor2. openGauss=# FETCH FORWARD 2 FROM cursor2; column1 | column2 ---------+--------- 0 | 3 1 | 2 (2 rows) -- Close the cursor and commit the transaction. openGauss=# CLOSE cursor2; CLOSE CURSOR -- End the transaction. openGauss=# END; COMMIT
Use the WITH HOLD cursor.
-- Start a transaction. openGauss=# START TRANSACTION; -- Set up the WITH HOLD cursor. openGauss=# DECLARE cursor1 CURSOR WITH HOLD FOR SELECT * FROM customer_t1; -- Fetch the first two rows in cursor1. openGauss=# FETCH FORWARD 2 FROM cursor1; c_customer_sk | c_customer_id | c_first_name | c_last_name | amount ---------------+---------------+--------------+-------------+-------- 3769 | | Grace | | 3769 | hello | | | (2 rows) -- End the transaction. openGauss=# END; COMMIT -- Fetch the next row in cursor1. openGauss=# FETCH FORWARD 1 FROM cursor1; c_customer_sk | c_customer_id | c_first_name | c_last_name | amount ---------------+---------------+--------------+-------------+-------- 6885 | maps | Joes | | 2200 (1 row) -- Close the cursor. openGauss=# CLOSE cursor1; CLOSE CURSOR
Use the MOVE statement.
```plaintext -- Start a transaction. openGauss=# START TRANSACTION; START TRANSACTION
-- Define cursor1. openGauss=# CURSOR cursor1 FOR SELECT * FROM customer_t1; DECLARE CURSOR
-- Skip the first three rows in cursor1. openGauss=# MOVE FORWARD 1 FROM cursor1; MOVE 1
-- Fetch the first two rows in cursor1. openGauss=# FETCH 2 FROM cursor1; c_customer_sk | c_customer_id | c_first_name | c_last_name | amount ---------------+---------------+--------------+-------------+-------- 3769 | hello | | | 6885 | maps | Joes | | 2200 (2 rows)
-- Close the cursor. openGauss=# CLOSE cursor1; CLOSE CURSOR
-- End the transaction. openGauss=# END; COMMIT ```