7.6.11. FOR SELECT

Used for

Looping row-by-row through a selected result set

Available in

PSQL

Syntax

  1. FOR <select_stmt> [AS CURSOR cursorname]
  2. DO <compound_statement>
Table 88. FOR SELECT Statement Parameters
ArgumentDescription

select_stmt

SELECT statement

cursorname

Cursor name. It must be unique among cursor names in the PSQL module (stored procedure, trigger or PSQL block)

single_statement

A single statement, terminated with a colon, that performs all the processing for this FOR loop

compound_statement

A block of statements wrapped in BEGIN…​END, that performs all the processing for this FOR loop

A FOR SELECT statement

  • retrieves each row sequentially from the result set and executes the statement or block of statements on the row. In each iteration of the loop, the field values of the current row are copied into pre-declared variables.

    Including the AS CURSOR clause enables positioned deletes and updates to be performed — see notes below

  • can embed other FOR SELECT statements

  • can carry named parameters that must be previously declared in the DECLARE VARIABLE statement or exist as input or output parameters of the procedure

  • requires an INTO clause that is located at the end of the SELECT …​ FROM …​ specification. In each iteration of the loop, the field values in the current row are copied to the list of variables specified in the INTO clause. The loop repeats until all rows are retrieved, after which it terminates

  • can be terminated before all rows are retrieved by using a LEAVE statement

The Undeclared Cursor

The optional AS CURSOR clause surfaces the set in the FOR SELECT structure as an undeclared, named cursor that can be operated on using the WHERE CURRENT OF clause inside the statement or block following the DO command, in order to delete or update the current row before execution moves to the next iteration.

Other points to take into account regarding undeclared cursors:

  1. the OPEN, FETCH and CLOSE statements cannot be applied to a cursor surfaced by the AS CURSOR clause

  2. the cursor name argument associated with an AS CURSOR clause must not clash with any names created by DECLARE VARIABLE or DECLARE CURSOR statements at the top of the body code, nor with any other cursors surfaced by an AS CURSOR clause

  3. The optional FOR UPDATE clause in the SELECT statement is not required for a positioned update

Examples using FOR SELECT

  1. A simple loop through query results:

    1. CREATE PROCEDURE SHOWNUMS
    2. RETURNS (
    3. AA INTEGER,
    4. BB INTEGER,
    5. SM INTEGER,
    6. DF INTEGER)
    7. AS
    8. BEGIN
    9. FOR SELECT DISTINCT A, B
    10. FROM NUMBERS
    11. ORDER BY A, B
    12. INTO AA, BB
    13. DO
    14. BEGIN
    15. SM = AA + BB;
    16. DF = AA - BB;
    17. SUSPEND;
    18. END
    19. END
  2. Nested FOR SELECT loop:

    1. CREATE PROCEDURE RELFIELDS
    2. RETURNS (
    3. RELATION CHAR(32),
    4. POS INTEGER,
    5. FIELD CHAR(32))
    6. AS
    7. BEGIN
    8. FOR SELECT RDB$RELATION_NAME
    9. FROM RDB$RELATIONS
    10. ORDER BY 1
    11. INTO :RELATION
    12. DO
    13. BEGIN
    14. FOR SELECT
    15. RDB$FIELD_POSITION + 1,
    16. RDB$FIELD_NAME
    17. FROM RDB$RELATION_FIELDS
    18. WHERE
    19. RDB$RELATION_NAME = :RELATION
    20. ORDER BY RDB$FIELD_POSITION
    21. INTO :POS, :FIELD
    22. DO
    23. BEGIN
    24. IF (POS = 2) THEN
    25. RELATION = ' "';
    26. SUSPEND;
    27. END
    28. END
    29. END
  3. Using the AS CURSOR clause to surface a cursor for the positioned delete of a record:

    1. CREATE PROCEDURE DELTOWN (
    2. TOWNTODELETE VARCHAR(24))
    3. RETURNS (
    4. TOWN VARCHAR(24),
    5. POP INTEGER)
    6. AS
    7. BEGIN
    8. FOR SELECT TOWN, POP
    9. FROM TOWNS
    10. INTO :TOWN, :POP AS CURSOR TCUR
    11. DO
    12. BEGIN
    13. IF (:TOWN = :TOWNTODELETE) THEN
    14. -- Positional delete
    15. DELETE FROM TOWNS
    16. WHERE CURRENT OF TCUR;
    17. ELSE
    18. SUSPEND;
    19. END
    20. END

See also

DECLARE CURSOR, LEAVE, SELECT, UPDATE, DELETE