Repeats the execution of a statement list once for each row in a cursor.
[ statement-label : ] FOR for-loop-name AS cursor-name [ cursor-type ] CURSOR { FOR statement [ FOR { UPDATE cursor-concurrency | FOR READ ONLY } ] | USING variable-name } DO statement-list END FOR [ statement-label ]
cursor-type : NO SCROLL | DYNAMIC SCROLL | SCROLL | INSENSITIVE | SENSITIVE
cursor-concurrency : BY { VALUES | TIMESTAMP | LOCK }
variable-name : identifier
NO SCROLL clause A cursor declared NO SCROLL is restricted to moving forward through the result set using FETCH NEXT and FETCH RELATIVE 0 seek operations.
As rows cannot be returned to once the cursor leaves the row, there are no sensitivity restrictions on the cursor. When a NO SCROLL cursor is requested, SQL Anywhere supplies the most efficient kind of cursor, which is an asensitive cursor. See Asensitive cursors.
DYNAMIC SCROLL clause DYNAMIC SCROLL is the default cursor type. DYNAMIC SCROLL cursors can use all formats of the FETCH statement.
When a DYNAMIC SCROLL cursor is requested, SQL Anywhere supplies an asensitive cursor. When using cursors there is always a trade-off between efficiency and consistency. Asensitive cursors provide efficient performance at the expense of consistency. See Asensitive cursors.
SCROLL clause A cursor declared SCROLL can use all formats of the FETCH statement. When a SCROLL cursor is requested, SQL Anywhere supplies a value-sensitive cursor. See Value-sensitive cursors.
SQL Anywhere must execute value-sensitive cursors in such a way that result set membership is guaranteed. DYNAMIC SCROLL cursors are more efficient and should be used unless the consistent behavior of SCROLL cursors is required.
INSENSITIVE clause A cursor declared INSENSITIVE has its membership fixed when it is opened; a temporary table is created with a copy of all the original rows. FETCHING from an INSENSITIVE cursor does not see the effect of any other INSERT, UPDATE, or DELETE statement, or any other PUT, UPDATE WHERE CURRENT, DELETE WHERE CURRENT operations on a different cursor. It does see the effect of PUT, UPDATE WHERE CURRENT, DELETE WHERE CURRENT operations on the same cursor. See Insensitive cursors.
SENSITIVE clause A cursor declared SENSITIVE is sensitive to changes to membership or values of the result set. See Sensitive cursors.
FOR UPDATE clause FOR UPDATE is the default. Cursors default to FOR UPDATE for single-table queries without an ORDER BY clause, or if the ansi_update_constraints option is set to Off. When the ansi_update_constraints option is set to Cursors or Strict, then cursors over a query containing an ORDER BY clause default to READ ONLY. However, you can explicitly mark cursors as updatable using the FOR UPDATE clause.
FOR READ ONLY clause A cursor declared FOR READ ONLY cannot be used in UPDATE (positioned), DELETE (positioned), or PUT statements. Because it is expensive to allow updates over cursors with an ORDER BY clause or a join, cursors over a query containing a join of two or more tables are READ ONLY and cannot be made updatable unless the ansi_update_constraints database option is Off. In response to any request for a cursor that specifies FOR UPDATE, SQL Anywhere provides either a value-sensitive cursor or a sensitive cursor. Insensitive and asensitive cursors are not updatable.
The FOR statement is a control statement that allows you to execute a list of SQL statements once for each row in a cursor. The FOR statement is equivalent to a compound statement with a DECLARE for the cursor and a DECLARE of a variable for each column in the result set of the cursor followed by a loop that fetches one row from the cursor into the local variables and executes statement-list once for each row in the cursor.
Valid cursor types include dynamic scroll (default), scroll, no scroll, sensitive, and insensitive.
The name and data type of each local variable is derived from the statement used in the cursor. With a SELECT statement, the data types are the data types of the expressions in the select list. The names are the select list item aliases, if they exist; otherwise, they are the names of the columns. Any select list item that is not a simple column reference must have an alias. With a CALL statement, the names and data types are taken from the RESULT clause in the procedure definition.
The LEAVE statement can be used to resume execution at the first statement after the END FOR. If the ending statement-label is specified, it must match the beginning statement-label.
The cursor created by a FOR statement is implicitly opened WITH HOLD, so statements executed within the loop that cause a COMMIT do not cause the cursor to be closed.
None.
None.
SQL/2008 The FOR statement is part of optional SQL/2008 language feature P002, "Computational completeness". As with the DECLARE CURSOR statement, the use of cursor-concurrency is a vendor extension, as are the combinations of cursor sensitivity and cursor scrollability options; see DECLARE CURSOR statement [ESQL] [SP]. The USING clause of the FOR statement is also a vendor extension.
The following fragment illustrates the use of the FOR loop.
FOR names AS curs INSENSITIVE CURSOR FOR SELECT Surname FROM Employees DO CALL search_for_name( Surname ); END FOR; |
This fragment also illustrates the use of the FOR loop.
BEGIN FOR names AS curs SCROLL CURSOR FOR SELECT EmployeeID, GivenName FROM Employees where EmployeeID < 130 FOR UPDATE BY VALUES DO MESSAGE 'emp: ' || GivenName; END FOR; END |
The following example shows the FOR loop being using inside of a procedure called myproc, which returns the top 10 employees from the Employees table, depending on the sort order specified when calling the procedure (asc for ascending, and desc for descending).
CALL sa_make_object( 'procedure', 'myproc' ) ; ALTER PROCEDURE myproc ( IN @order_by VARCHAR(20) DEFAULT NULL ) RESULT ( Surname person_name_t ) BEGIN DECLARE @sql LONG VARCHAR; DECLARE @msg LONG VARCHAR; DECLARE LOCAL TEMPORARY TABLE temp_names( surnames person_name_t ); SET @sql = 'SELECT TOP(10) * FROM Employees AS t ' ; CASE @order_by WHEN 'asc' THEN SET @sql = @sql || 'ORDER BY t.Surname ASC'; SET @msg = 'Sorted ascending by last name: '; WHEN 'desc' THEN SET @sql = @sql || 'ORDER BY t.Surname DESC'; SET @msg = 'Sorted ascending by last name: '; END CASE; FOR loop_name AS SCROLL CURSOR USING @sql DO INSERT INTO temp_names( surnames ) VALUES( Surname ); MESSAGE( @msg || Surname ) ; END FOR; SELECT * FROM temp_names; END ; |
Calling the myproc procedure and specifying asc (for example, CALL myproc( 'asc' );
) returns the following results:
Surname |
---|
Ahmed |
Barker |
Barletta |
Bertrand |
Bigelow |
Blaikie |
Braun |
Breault |
Bucceri |
Butterfield |
Discuss this page in DocCommentXchange.
|
Copyright © 2010, iAnywhere Solutions, Inc. - SQL Anywhere 12.0.0 |