Anda di halaman 1dari 11

How Many Rows Did SQL Fetch?

Published: March 29, 2006

Hey, Ted:
I am using SQL to load a subfile. Since there are 16 subfile records to a page, I fetch 16 database records into a data structure. However, the fetch does not always return 16 rows. Sometimes it returns fewer. How can I tell how many data structure occurrences were fetched? --Lynn

You will need to check the SQLER3 field of the SQL Communications Area (SQLCA). I wrote about this field earlier in Four Hundred Guru. See "How Many Records Did SQL Delete?" Here's an example I threw together that you can start from. It fetches seven records at a time from file QCUSTCDT, which you should be able to find in library QIWS on your system.
Fqsysprt D D D D CustRec RecCt Index FetchCt o f 132 printer extname(QCUSTCDT) occurs(7) inz 3p 0 10i 0 3p 0

e ds s s s

C eval *inlr = *on C/exec sql C+ declare c1 cursor for C+ select * C+ from qcustcdt C/end-exec C/exec sql C+ open c1 C/end-exec C dow '1' C/exec sql C+ fetch c1 C+ for 7 rows C+ into :CustRec C/end-exec C if sqlstt <> *zeros C leave C endif C eval FetchCt += 1 C for index = 1 to SqlEr3 C eval RecCt += 1 C index occur CustRec C except pline C endfor C enddo C/exec sql C+ close c1 C/end-exec C return Oqsysprt e pline 1 O FetchCt 4


RecCt SQLEr3 cusnum lstnam init

+0001 +0001 +0001 +0001 +0001

The program has two loops. The outer loop fetches up to seven rows into a multiple-occurrence data structure. The inner loop processes the data that was placed into the data structure. Notice that the SQLER3 field serves to limit the number of iterations of the inner loop. Here's the output I got when I ran the program. The first column counts the fetches. Notice that the program had to fetch twice to access 12 rows. The second column numbers the records. The third column is SQLER3. It shows that the first fetch retrieved seven rows, whereas the second fetch retrieved five. The remaining columns come from the database file.
1 1 1 1 1 1 1 2 2 2 2 2 1 2 3 4 5 6 7 8 9 10 11 12 000000007 000000007 000000007 000000007 000000007 000000007 000000007 000000005 000000005 000000005 000000005 000000005 938472 839283 392859 938485 397267 389572 846283 475938 693829 593029 192837 583990 Henning Jones Vine Johnson Tyron Stevens Alison Doe Thomas Williams Lee Abraham G B S J W K J J A E F M K D S A E L S W N D L T


The SQL precompiler automatically places the SQLCA in the definition specifications of the ILE RPG for AS/400 program prior to the first calculation specification. INCLUDE SQLCA should not be coded in the source program. If the source program specifies INCLUDE SQLCA, the statement will be accepted, but it is redundant. The SQLCA, as defined for ILE RPG for AS/400:
D* SQL Communications area D SQLCA DS D SQLAID 1 8A D SQLABC 9 12B D SQLCOD 13 16B D SQLERL 17 18B D SQLERM 19 88A D SQLERP 89 96A D SQLERRD 97 120B D SQLERR 97 120A D SQLER1 97 100B D SQLER2 101 104B D SQLER3 105 108B D SQLER4 109 112B D SQLER5 113 116B D SQLER6 117 120B

0 0 0 0 DIM(6) 0 0 0 no of records fetched by cursor 0 0 0


121 121 122 123 124 125 126 127 128 129 130 131 132

131A 121A 122A 123A 124A 125A 126A 127A 128A 129A 130A 131A 136A

Note: Variable names in RPG for AS/400 are limited to 6 characters. The standard SQLCA names were changed to a length of 6 for RPG for AS/400. To maintain compatibility with RPG for AS/400 programs which are converted to ILE RPG for AS/400, the names for the SQLCA will remain as used with RPG for AS/400. The SQLCA defined for the ILE RPG for AS/400 has added the field SQLERRD which is defined as an array of six integers. SQLERRD is defined to overlay the SQLERR definition.

How Many Records Did SQL Delete?

Hey, Ted:
I have an RPG IV program with an embedded SQL DELETE statement. Is it possible for my program to determine how many records are deleted when the statement executes?


DB2/400 returns this information to you through a subfield of the SQL communications area (SQLCA), a data area that is automatically included in your RPG program when you compile. You can refer to this subfield by either of two names: SQLERRD(3) or SQLER3. When a DELETE, UPDATE, or INSERT operation completes normally, DB2 updates the subfield with the number of rows that qualified for the operation.
C/exec sql C+ C+ C/end-exec /free delete from somefile where company = :company if SQLER3 > *zero;

I understand that RPG is the only compiler that includes the SQLCA by default. According to the SQL Reference, the COBOL, C, PL/I, and FORTRAN programs must use the SQL INCLUDE command to reference the SQLDA. In the following short COBOL program, the SQLCA is included in the workingstorage section.
Identification division. Program-ID. SQL005. Environment division. Data division. Working-storage section. 01 Company pic s999 01 EmptySet pic x.


Exec SQL include SQLCA end-exec. Procedure division. Main-logic. Exec SQL set option commit=*none end-exec. Exec SQL delete from qtemp/cuxt where company = 99 end-exec. if SQLERRD(3) > zero move "N" to EmptySet else move "Y" to EmptySet end-if. goback.

For more information about the SQLCA, consult the DB2 reference on IBM's Web site.

From Wikibooks, the open-content textbooks collection

< SQL Jump to: navigation, search This is a work in progress to which a lot more info will be added. Please be patient. SQL/400 is a proprietory dialect of SQL for the IBM AS/400, which was later rebranded as iSeries and finally as SystemI, business eServer Computer Platform. It comes in several flavors, or ways that SQL can be run.

Interactive SQL/400 which can be run from the Command line. Invoke STRSQL {Start SQL/400} and get at what looks like another command line, where we can key in SQL statements for immediate execution, and/or use the F4 Prompt function to navigate IBM DB2/400 data base, which is a version of UDB, IBM's Universal Data Base to get at the 400'ds files (tables) and their fields (columns), for incorporation in the SQL statement. Interactive SQL/400 is often used to identify statements needed to perform various programming actions. When exiting an Interactive SQL/400 session, we have the option of saving a log of our activity, from which our successful SQL/400 statements may be copied into one of the other flavors of SQL/400. SQL Query Manager is used to design and store SQL queries used to extract information, generate reports, and create procedures. Query Manager is an interface to SQL in which end users, unfamiliar with SQL, the programming language, can be prompted through what is needed to create inquiries and reports that are more sophisticated than what can be created by other tools, and can be rerun as needed. Static Embedded SQL involves SQL statements hard coded inside another high level language program, such as RPG/400, Cobol/400, C/400, REXX, PL/1, and Fortran/400. This is done because there are some areas where SQL is more powerful than other languages, but there are some things they can do that SQL can not. See Comparative Computer Languages. So the AS/400 programmer can pick and choose the Computer Language that is best suited to the needed function, with programs in different languages calling code in other languages a variety of ways. Dynamic Embedded SQL

All the AS/400 languages that support Static Embedded SQL also support Dynamic Embedded SQL.

Other SQL/400 Applications. Suppose you connect to the AS/400 using a Personal Computer which has many PC Applications, such as Microsoft Excel. You can put SQL statements inside an Excel cell which will access the AS/400 data base. When you open the Excel, it immediately shows you the latest data from the data base. You can then change the statements to change what data is selected for the Excel.



1 Interactive SQL/400 2 SQL Query Manager 3 Languages that support Embedded SQL 4 Static Embedded SQL o 4.1 SQL embedded in RPG o 4.2 SQL embedded in Cobol o 4.3 Static SQL SELECT Modes 4.3.1 SQL Cursor 5 Dynamic Embedded SQL 6 Other SQL/400 Applications

[edit] Interactive SQL/400 [edit] SQL Query Manager [edit] Languages that support Embedded SQL

C/400 Cobol/400 RPG (many different versions of RPG on the 400) REXX PL/1 Fortran/400

[edit] Static Embedded SQL

Static Embedded SQL statments are written into the source code of the high level language program, then an SQL Precompiler converts the SQL statements to a form that is acceptable to the high level language compiler. Dynamic SQL Statements are composed, prepared and run when the program is run.

[edit] SQL embedded in RPG

SQL statements can be placed within the calculations of an RPG program ... detail calculations, total calculations, or an RPG Subroutine. RPG identifies what section of a program, using a character in position 6 with a C for calculations. Here is how SQL statements are usually embedded in RPG program calculations.

C/EXEC SQL C+ SQL Statement C+ SQL Statement C+ SQL Statement C/END-EXEC

There can be any number of SQL Statements. Notice the slash at beginning of the first and last lines, that delineate the beginning and end of the SQL statements embedded in the RPG code. Notice the plus sign at the beginning of each SQL statement.

[edit] SQL embedded in Cobol

In Cobol, SQL statements are embedded in specific program sections. The END-EXEC must be terminated with a period.
EXEC SQL SQL Statement SQL Statement END-EXEC.

There can be any number of SQL statements.

[edit] Static SQL SELECT Modes

Static SQL offers two modes of operation, with secondary options.

SELECT one row of a table, at a time. SELECT multiple rows of one or more tables into a Cursor. o A Serial Cursor is when each row of the results is to be fetched only once per open of the cursor, going through the data sequentially. Each time a row of data is read into the program, the cursor is moved to the next row of the result table. This is repeated until reaching end-of-data, when the cursor should be closed. To use the cursor again, close the current use of it, then re-issue the open statement. We cannot back up in a Serial Cursor. o A Scroll Cursor supports alternatives to going through the data sequentially. Access defaults to the Serial Cursor method, while the Fetch statement can position the cursor where to do the reading. When it is not specified that the Scroll Cursor is Dynamic, access is read-only. This kind of Cursor is usually in a program to display parts of the data base on screen of end user, who can then key in something to navigate the data, leading the Scroll Cursor to be positioned elsewhere in the data, to get what the user wants to see. o A Dynamic Scorll Cursor permits the update of rows that are accessed.

[edit] SQL Cursor There are several ways this can be programmed. One way is to define a Data Structure which defines all the data elements that will be selected with each occurrence of

executing the multiple rows. It reads in the data from the joined files very similar to reading a record from one file in RPG or Cobol. Unlike many other AS/400 programming languages, where Variables can be defined wherever needed, such at the beginning of some Subroutine that will be using them, SQL/400 requires that anything, to be used in the program, where the SQL is embedded, be defined earlier in the program source code than where ever it is subsequently used. Thus, the sequence of processing an SQL cursor, embedded in another high level language, is: 1. 2. 3. 4. 5. Declare Cursor Open Cursor Fetch Rows using Select Optionally Delete or Update Close Cursor

[edit] Dynamic Embedded SQL

AS/400 SQL performance

Rune Oynes 06-06-1999, 08:35 PM I em using Prepared Statement, with AS400 JDBC. (PS) The first time i uses the PS it is very slow, the next time i use the PS it is faster. Why does this happend, and what can i do to make it faster also the first time i execute a P.S. I know there is thomthing like a Calable Statment, will this help and how do i create it on the AS400. Best Regards Rune Oynes

Stuart Payne 06-10-1999, 07:20 AM I have experience the same thing and from what I observe is the following. The first time you call the statement, it creates a cursor of the data you are selecting. This is similar to another index (logical file) on the table or an access path of an Open Query File. This cursor will be re-used for other statement calls, which makes it run faster. When you create a SQLRPGLE, there is a parameter to close the cursor when the activation group or module is closed. The default from IBM is *ENDACTGRP. ( Close SQL cursor . . . . . . . . > *ENDACTGRP *ENDMOD, *ENDACTGRP )

So I am assuming that IBM keeps the SQL cursor open until the activation group has ended. To speed up the statement call the first time, look at the using another index (logical file), the optimize option, or put the SQL in debug and analyze what is happening. To debug the SQL you execute the STRDBG command, run your SQL, and then look at your job log.

Rune Oynes 06-10-1999, 09:11 PM

Rune Oynes 06-10-1999, 11:29 PM IS IT POSIBLE TO PREVENT THE ODP to be creted eatch time a user start his application. I have tryed the debugger on AS400 (STRSRVJOB on the QZDASOINI job and STRDBG) I see the message ODP created,1 or 2 times after that i get "ODP reused", When i se "ODP created" it takes 30sek before the resultset is ready, when i se the message ODP reused, the responce time is 3 sek. Best Ragards Rune

Stuart Payne 06-16-1999, 05:10 AM You need the ODP. There are some tricks you can try to speed up the ODP. If you are re-ordering the data, as well as selecting on certain values, then use or create a logical file that has the same order. Another suggestion is to look at the "Optimize For n Rows" in the Select clause. By using the "Optimize For ## Rows", the SQL optimzer will choose the most efficient way to return the number of rows found in ##. You can also try and open the data path by another application and leave it open. Caution is required on this action because it may effect other applications. File size is another factor. the smaller the file, the quicker the ODP can be establish. Since Mike C. is the forum director, you should probably e-mail him for any other techniques.


Description iSeries SQL/400 is a self-paced, audio-cassette course providing comprehensive, practical training in SQL/400 and its functions. Upon completion you'll be able to: Create a database (SQL collection) using SQL data definition language statements. Populate an SQL collection using SQL data manipulation language statements. Use the SQL interactive environment to select, sequence, join, and summarize data from SQL tables and iSeries files. Use SQL queries to extract information about the SQL collection itself. Use SQL statements to access physical and logical files created outside of the SQL collection. Use SQL interfaces within RPG/400 and COBOL/400 programs. Use SQL calls in interactive HLL programs that dynamically create access paths to data. Create reports using Query Management Queries and Forms. Pass parameters from HLL programs to Query Management Queries. Convert Query/400 queries to Query Management Queries and Forms. SQL Data Manipulation Statements SELECT INSERT UPDATE WHERE GROUP BY UNION SQL Predicates and Functions Commitment Control Query Management Queries and Forms Creating Queries and Forms Passing HLL Parameters to Queries Converting Query/400 to QM Queries and Forms Interactive SQL/400 STRSQL (Start SQL) Command Setting and Saving SQL Session Defaults SQL Entry Screen Executing SQL Statements Embedded SQL/400 in HighLevel Languages COBOL and RPG Examples Accessing SQL Tables and Cursors Serial and Scrollable Cursors Updateable Cursors Dynamic Data Selection SQL Precompiler SQL Optimizer SQL/400 Subqueries Interactive and Embedded Simple Subqueries Compound Subqueries Correlated Subqueries

SQL Concepts Using SQL across Multiple Operating Systems Collections Tables Rows and Columns Views Indexes Cursors Communication Areas SQL Data Definition Statements CREATE COLLECTION CREATE TABLE CREATE VIEW CREATE INDEX Documenting the Data Base Model

With SQL for RPG Programmers youll quickly modernize your RPG skills. Instead of relying solely on limited RPG file operations, youll add the power and convenience of SQL to your RPG programming. SQL is a powerful, convenient and universal tool and, if you program with RPG, there's no better way to learn SQL than to actually see how it is used in RPG programs. Using the SQL pre-compiler, youll embed SQL statements in your RPG code. With SQL youll put more "ease of use" and functionality into your RPG programs. You'll work with data returned by SELECT statements and use INSERT, UPDATE and DELETE statements to make changes.

Here's is what you will learn:

Work with host variables to pass data from RPG to SQL statements Unsure of the syntax of an SQL statement? Develop and test SQL statements in the Interactive SQL environment, copy/paste the working statements into RPG Work with data returned from SQL SELECT statements in your RPG programs using cursors Cursors: read-only and updateable, serial, scroll and dynamic: know when and how to use each Boost SQL performance with DECLARE and PREPARE SELECT statement options to get just the data you want: LIKE, IN, BETWEEN, NOT and multiple conditions Work with column functions for statistics, summing and counting See how using GROUP BY gives you "level break" type functionality in SQL Develop and test RPG code with joins: inner join, outer joins, exception join and cross join The power of one: how to combine SQL statements into one statement, using subselects, correlated subqueries, nested tables and joins Simplify SQL error handling in your code with the WHENEVER statement Use the SQL Communication Area to get all information about an SQL error or warning

Youll learn how to create new files quickly and easily in an RPG program, without needing to call system commands. Developed by programmers for programmers, this hands-on SQL training shows you plenty of short-cuts, gives you tips and real-world advice on how to develop and test statements. Most importantly, youll learn by running actual code on your system. SQL for RPG Programmers includes over a dozen RPG coding labs where you'll develop, test and debug RPG code using embedded SQL. This is gold!