SQL Cursor Definitions
Preparing SQL cursors
Scroll cursors support modifications as well as all cursor directional options such as FETCH NEXT, FETCH FIRST, FETCH LAST, FETCH PRIOR, FETCH RELATIVE and FETCH ABSOLUTE. In addition, changes to the underlying tables are reflected in the cursor. The downside is that the cursor is re-evaluated on each call. The example listed shows a scroll cursor being prepared from a variable character string. The string is formatted to use as the select statement in the PREPARE clause. The DECLARE clause defines the cursor as a scroll-type cursor.
Scroll Cursor
IF %parms >= 1 and orderby > *blanks ; OrderString = %trim(orderBy) ; ELSE ; OrderString = dftorder ; ENDIF ; IF %parms > 1 and SelectOnly > *blanks ; SelectString = %trim(SelectOnly) ; ELSE ; SelectString = dftSelect ; ENDIF ; QRYstring = %trim(SelectString) + ' ' + %trim(OrderString) ; // Declare the SQL cursor to hold the data // Open the SQL cusror EXEC SQL PREPARE selStmt FROM :QRYstring ; EXEC SQL DECLARE XFCursor SCROLL CURSOR FOR selStmt ; EXEC SQL OPEN XFCursor ; IF SQLSTT = SQLSTTOK ; erroroccurred = *OFF ; ELSE ; erroroccurred = *ON ; ENDIF ;
Dynamic Cursor
The code below defines a dynamic cursor. The selection is prepared with the question marks representing a replacement variable as filters in the WHERE clause. When the cursor is opened, the OPEN statement must include the USING clause to supply the variables to be inserted into the select statement.
Dcl-Proc SetPaymentCursor Export; Dcl-PI SetPaymentCursor ind ; End-PI ; Dcl-s isFound ind inz(*off) ; Dcl-s errorOccurred ind inz(*off) ; Dcl-s qt char(1) inz('''') ; Dcl-s QRYstring char(1024) ; Dcl-s len zoned(3:0) ; //*--------------------------------- //* Substring and concatenate the //* transaction date to cast as a //* date type field for the compare. //*--------------------------------- QRYstring = 'Select * From VayPay Where vaLoan = ? + and vtxfer = ? and vacode <> ''cnv'' and + CAST( concat(substr(DIGITS(VATRDTE),1,4),concat(''-'', + concat(substr(DIGITS(VATRDTE),5,2),concat(''-'', + substr(DIGITS(VATRDTE),7,2))))) AS DATE) + >= ? and + CAST( concat(substr(DIGITS(VATRDTE),1,4),concat(''-'', + concat(substr(DIGITS(VATRDTE),5,2),concat(''-'', + substr(DIGITS(VATRDTE),7,2))))) AS DATE) + <= ? '; EXEC SQL PREPARE selectString FROM :QRYstring; EXEC SQL DECLARE payment4048Cursor SCROLL CURSOR FOR selectString; IF SQLSTT = SQLSTTOK ; ErrorOccurred = *off ; ELSE ; ErrorOccurred = *ON ; ENDIF ; RETURN ErrorOccurred ; End-Proc SetPaymentCursor ; . . . Exec SQL open Payment4048Cursor using :shloan,:shtxfer,:shblfrdt,:shbltodt; If SQLstt = SQLsttOK; csrOpen = *on; EndIF;
Insensitive Cursor
The insensitive cursor executes the query and stores the entire set of data that is used for the cursor in tempdb. Thus, the query is only run once and the data is static. The result of this is good performance, since the cursor query is only run once, but no modifications to the cursor can be made, nor are changes made to the underlying tables reflected in the cursor. With an insensitive cursor, only FETCH NEXT is supported.
Exec SQL select count(*) into :rowCount From EFSCTLPF Where ecarea = :thisArea and ecname = :thisName ; EXEC SQL declare EFScript240 insensitive cursor for (select * from EFSCTLPF Where ecArea = :thisArea and ecName = :thisName order by ecseqn); Exec SQL open EFScript240 ; EXEC SQL fetch EFScript240 for :rowCount rows into :detail;