Declares a cursor.
DECLARE cursor-name [ UNIQUE ] [ NO SCROLL | DYNAMIC SCROLL | SCROLL | INSENSITIVE | SENSITIVE ] CURSOR FOR { select-statement | statement-name | call-statement }
DECLARE cursor-name [ NO SCROLL | DYNAMIC SCROLL | SCROLL | INSENSITIVE | SENSITIVE ] CURSOR { FOR select-statement | FOR call-statement | USING variable-name }
cursor-name : identifier
statement-name : identifier | hostvar
variable-name : identifier
UNIQUE clause When a cursor is declared UNIQUE, the query is forced to return all the columns required to uniquely identify each row. Often this means ensuring that all columns in the primary key or a uniqueness table constraint are returned. Any columns that are required but were not specified in the query are added to the result set.
A DESCRIBE done on a UNIQUE cursor sets the following additional options in the indicator variables:
DT_KEY_COLUMN The column is part of the key for the row.
DT_HIDDEN_COLUMN The column was added to the query because it was required to uniquely identify the rows.
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.
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.
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. With a value-sensitive cursor, a subsequent FETCH of a previously FETCHed result row may return a warning or an error if the underlying row has been modified or deleted.
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 from concurrently-executing transactions, or any other update operations from within the same transaction. INSENSITIVE cursors are not updatable.
SENSITIVE clause A cursor declared SENSITIVE is sensitive to changes to membership or values of the result set.
FOR statement-name clause Statements are named using the PREPARE statement. Cursors can be declared only for a prepared SELECT or CALL. The cursor updatability specified in the PREPARE statement is used for the cursor, unless the SQL preprocessor -m HISTORICAL option is specified.
USING variable-name clause For use within stored procedures only. The variable is a string containing a SELECT statement for the cursor. The variable must be available when the DECLARE is processed, and so must be one of the following:
A parameter to the procedure. For example:
CREATE FUNCTION GetRowCount( IN qry LONG VARCHAR ) RETURNS INT BEGIN DECLARE crsr CURSOR USING qry; DECLARE rowcnt INT; SET rowcnt = 0; OPEN crsr; lp: LOOP FETCH crsr; IF SQLCODE <> 0 THEN LEAVE lp END IF; SET rowcnt = rowcnt + 1; END LOOP; CLOSE crsr; RETURN rowcnt; END; |
Nested inside another BEGIN...END after the variable has been assigned a value. For example:
CREATE PROCEDURE get_table_name( IN id_value INT, OUT tabname CHAR(128) ) BEGIN DECLARE qry LONG VARCHAR; SET qry = 'SELECT table_name FROM SYS.SYSTAB ' || 'WHERE table_id=' || string(id_value); BEGIN DECLARE crsr CURSOR USING qry; OPEN crsr; FETCH crsr INTO tabname; CLOSE crsr; END END; |
Cursors are the primary means for manipulating the results of queries. The DECLARE CURSOR statement declares a cursor with the specified name for a SELECT statement or a CALL statement. In a Watcom SQL procedure, trigger, or batch, a DECLARE CURSOR statement must appear with other declarations, immediately following the BEGIN keyword. Cursor names must be unique.
If a cursor is declared inside a compound statement, it exists only for the duration of that compound statement (whether it is declared in a Watcom SQL or Transact-SQL compound statement).
The type of cursor specified in a DECLARE CURSOR statement can dictate the execution plan selected by the query optimizer for that statement. For example, an INSENSITIVE cursor over a SELECT statement requires the complete materialization of the result set of the SELECT statement when the cursor is opened. Moreover, the type of cursor must match the characteristics of the underlying statement. If there is a mismatch between the cursor type and the statement, then the cursor type may be changed automatically. For example, an INSENSITIVE cursor declaration conflicts with an updatable SELECT statement that specifies FOR UPDATE, since by definition INSENSITIVE cursors are read only. In this case, the cursor type is changed automatically from INSENSITIVE to an updatable, value-sensitive cursor when the cursor is opened.
If the updatability of a SELECT statement embedded in a cursor declaration is unspecified, it is determined by the setting of the ansi_update_constraints option.
None.
If the cursor type must be changed to satisfy the requirements of the underlying statement, a warning is returned when the cursor is opened.
SQL/2008 DECLARE CURSOR is a core feature of the SQL/2008 standard. The ability to specify FOR UPDATE with SCROLL or NO SCROLL is optional SQL language feature F831, "Full cursor update". Using DECLARE CURSOR in an embedded SQL program constitutes optional SQL language feature B031. Some cursor types are also optional SQL features. These include:
INSENSITIVE cursors are optional SQL language feature F791 of the SQL/2008 standard.
SENSITIVE cursors are optional SQL language feature F231 of the SQL/2008 standard.
Scrollable cursors are optional SQL language feature F431 of the SQL/2008 standard.
SQL Anywhere supports a number of vendor extensions to DECLARE CURSOR, including:
SQL Anywhere supports several extensions to the FOR UPDATE clause, which SQL/2008 defines as a clause of the DECLARE CURSOR statement.
WITH HOLD is specified as a clause of the OPEN statement, rather than as a clause of the DECLARE CURSOR statement as defined in SQL/2008.
The SQL/2008 standard separates the notions of cursor sensitivity and scrollability, while for historical reasons SQL Anywhere combines the two. In SQL Anywhere, all cursors are forward-and-backward scrollable except for those declared as NO SCROLL.
DYNAMIC SCROLL and UNIQUE are vendor extensions. DYNAMIC SCROLL has similar behavior to cursors declared as ASENSITIVE in the SQL/2008 standard.
The ability to declare a cursor over a CALL statement, or with a USING clause, is a vendor extension.
Transact-SQL DECLARE CURSOR is supported by Adaptive Server Enterprise, but there are several behavioral differences. Adaptive Server Enterprise differentiates, as in SQL/2008, between scrollability and sensitivity; in Adaptive Server Enterprise, cursor sensitivity options are SEMI-SENSITIVE, INSENSITIVE, or default (akin to ASENSITIVE). In Adaptive Server Enterprise, NO SCROLL cursors are the default, and all scrollable cursors are read-only. Several features of the DECLARE CURSOR statement are not supported by Adaptive Server Enterprise. These include:
Adaptive Server Enterprise does not support the SQL Anywhere cursor concurrency clause.
To acquire a lock on a fetched row, you must use the HOLDLOCK table hint.
Adaptive Server Enterprise does not support DYNAMIC SCROLL or UNIQUE cursors. DYNAMIC SCROLL is similar to Adaptive Server Enterprise default cursor behavior.
The ability to declare a cursor over a CALL statement, or with a USING clause, is not supported by Adaptive Server Enterprise.
In Adaptive Server Enterprise, Transact-SQL procedures and functions can contain multiple DECLARE CURSOR statements that use the same cursor name. In Adaptive Server Enterprise, the DEALLOCATE CURSOR statement is used to eliminate a cursor from the current scope, so that a subsequent OPEN statement can reference the correct, previously-declared cursor. This feature is not supported in SQL Anywhere. In SQL Anywhere, all cursors in a given scope must have unique names. If a Transact-SQL dialect procedure contains multiple cursor declarations with the same name, the procedure parses without error. However, at execution time, if a second DECLARE CURSOR statement with the same cursor name is executed, an error occurs.
You should be aware that the TDS wire protocol for Open Client and jConnect connections does not implement true scrollable result sets. When scrolling backward through a cursor, the FETCH request may be satisfied immediately if the desired row is within a window of prefetched rows that have already been retrieved by the TDS client. If the desired row is beyond this window, however, the cursor's SELECT statement may be re-executed.
The following example illustrates how to declare a scroll cursor in embedded SQL:
EXEC SQL DECLARE cur_employee SCROLL CURSOR FOR SELECT * FROM Employees; |
The following example illustrates how to declare a cursor for a prepared statement in embedded SQL:
EXEC SQL PREPARE employee_statement FROM 'SELECT Surname FROM Employees'FOR READ ONLY; EXEC SQL DECLARE cur_employee CURSOR FOR employee_statement; |
The following example illustrates the use of cursors in a stored procedure:
BEGIN DECLARE cur_employee CURSOR FOR SELECT Surname FROM Employees; DECLARE name CHAR(40); OPEN cur_employee; lp: LOOP FETCH NEXT cur_employee INTO name; IF SQLCODE <> 0 THEN LEAVE lp END IF; ... END LOOP; CLOSE cur_employee; END |
Discuss this page in DocCommentXchange.
|
Copyright © 2012, iAnywhere Solutions, Inc. - SQL Anywhere 12.0.1 |