fhg
Volume 9, Number 16 -- May 13, 2009

SQL's Other Fetch Options

Published: May 13, 2009

by Ted Holt

I consider fetch a great word, and lament that it is no longer used in daily English, at least not where I live, except maybe when speaking to dogs. Fortunately, fetch is still used heavily in SQL. High-level language programs need it to convert set-at-a-time processing into row-at-a-time processing. Fetch can do more than read a result set from beginning to end. Do you know what else it can do?

From Top to Bottom

For starters, let's look at the most common use of fetch--to read an SQL cursor from beginning to end. The following highly sophisticated demonstration program shows how it's done.

Fqsysprt   o    f  132        printer 

D Customer        ds                  qualified inz 
D   Number                       6p 0 
D   LastName                     8a 
D   Initials                     3a 
D   City                         6a 
D   State                        2a 
D   BalanceDue                   7p 2 

D SqlEof          c                   const('02000') 
D DetailLine      s            132a  

D Print           pr       
D   Data                       132a   value

 /free 
     *inlr = *on; 
     exec sql 
        declare Input cursor for 
           select CUSNUM, LSTNAM, INIT, CITY, STATE, BALDUE
             from qcustcdt 
            where baldue <> 0 
            order by baldue desc; 

     exec sql 
        open Input; 

     dow '1'; 
        exec sql 
           fetch Input into :Customer; 
        if sqlstt >= SqlEof; 
           leave; 
        endif; 
        Print (%editc(Customer.BalanceDue:'J') + ' ' + 
               Customer.LastName + ' ' + 
               Customer.Initials + ' ' + 
               %editc(Customer.Number:'4') + ' ' + 
               %trimr(Customer.City) + ', ' + Customer.State);
     enddo;      
     return;  
 /end-free 

Oqsysprt   e            PrintLine   1 
O                       DetailLine 
 * ==========================================================
P Print           b 
D                 pi 
D   Data                       132a   value 
 /free 
     DetailLine = Data; 
     except PrintLine; 
 /end-free 
P                 e 

Notice the cursor declaration at the top of the free-format calculation specs. I chose to name my cursor Input.

exec sql  
   declare Input cursor for 
      select CUSNUM, LSTNAM, INIT, CITY, STATE, BALDUE
        from qcustcdt 
       where baldue <> 0 
       order by baldue desc; 

Notice the open.

exec sql 
   open Input; 

Notice the fetch.

fetch Input into :Customer; 

This command tells the system to retrieve one row of the result set and place the data into data structure Customer.

This form of fetch is abbreviated. Here is the full fetch command.

fetch next from Input into :Customer;

Also, in order to keep the example succinct, I omitted error handling.

From Bottom to Top

You may also read a cursor backward. The following modifications to the previous example show how.

exec sql  
   declare Input scroll cursor for 
      select CUSNUM, LSTNAM, INIT, CITY, STATE, BALDUE
        from qcustcdt 
       where baldue <> 0 
       order by baldue desc; 

exec sql  
   open Input; 
exec sql 
   fetch after from Input; 

dow '1'; 
   exec sql 
      fetch prior from Input into :Customer; 
   if sqlstt >= SqlEof; 
      leave; 
   endif; 
   Print ( ... etc. ...)
enddo; 

First, notice the cursor declaration. I've added the scroll keyword in order to make the cursor scrollable. That is, the cursor permits random access.

Second, FETCH AFTER positions to the end of the record set. This is similar to using the SETGT in native RPG I/O in order to position to the end of the file. (FETCH BEFORE positions to the beginning of the file, by the way.)

Third, notice the FETCH PRIOR operation. Like RPG's READP opcode, this fetch retrieves the previous row in the return set.

Fetch First and Last

You can retrieve the first and last rows of an SQL query. You'll need a scrollable cursor, of course. Use FETCH FIRST and FETCH LAST, as in the following example.

exec sql 
   declare Input scroll cursor for 
      select CUSNUM, LSTNAM, INIT, CITY, STATE, BALDUE
        from qcustcdt 
       where baldue <> 0 
       order by baldue desc; 

exec sql 
   open Input; 
exec sql 
   fetch last from Input into :Customer; 
   ... do something ...
exec sql 
   fetch first from Input into :Customer; 
   ... do something ...

Read It Again

At times you may need to re-read a fetched record. This feature is helpful when the data may have changed in the database and you want to refresh the data in your host variables. Use FETCH CURRENT to re-read the row that was last fetched. Here's how it's done.

/free 
exec sql 
   declare Input sensitive scroll cursor for 
      select CUSNUM, LSTNAM, INIT, CITY, STATE, BALDUE
        from qcustcdt 
       where baldue <> 0 
       order by baldue desc; 

     exec sql 
   open Input; 

exec sql 
   fetch first from Input into :Customer; 

.... more stuff ....


// re-read
exec sql 
   fetch current from Input into :Customer; 

Take a look at the cursor definition. I've added the word SENSITIVE to indicate that I want the cursor to reflect the latest changes to the database.

I used FETCH FIRST to retrieve the first row from the result set. Later, FETCH CURRENT re-reads the same row from the cursor.

Fetch Relative

Normal practice is to read a cursor sequentially, but FETCH RELATIVE allows a deviation from the practice. The form is FETCH RELATIVE n, where n is the number of rows before (if n is negative) or after (if n is positive) the last fetched row. The following code reads the odd-numbered rows from the result set, by reading the first row, then every second row following.

exec sql 
   declare Input scroll cursor for 
      select CUSNUM, LSTNAM, INIT, CITY, STATE, BALDUE
        from qcustcdt 
       where baldue <> 0 
       order by baldue desc; 

exec sql 
   open Input; 

exec sql 
   fetch first from Input into :Customer; 

dow sqlstt < SqlEof; 
   Print (... etc. ...);
   exec sql 
      fetch relative +2 from Input into :Customer; 
enddo; 

If Only. . .

I hope this brief look at FETCH gives you some fodder for new ideas. I am asked from time to time if SQL allows random positioning over a cursor by key, similar to the way that RPG SETLL and COBOL START allow random positioning over a keyed file. I wish it were so, but it is not. Shucks! That would be handy.




                     Post this story to del.icio.us
               Post this story to Digg
    Post this story to Slashdot


Sponsored By
PRODATA COMPUTER SERVICES

Simplify your iT!

DBU - super easy to use. The leading data access tool on the market.

DBU RDB - does the work for you. Analyze data on all your servers.
MySQL, Microsoft SQL Server, Oracle, DB2 databases and others.

RDB Connect - programmatic access to remote data! Full SQL access to
remote databases from all System i high-level languages.

Download your free trials NOW.
Order today and SAVE $$$!
www.prodatacomputer.com
800.228.6318


Senior Technical Editor: Ted Holt
Technical Editor: Joe Hertvik
Contributing Technical Editors: Edwin Earley, Brian Kelly, Michael Sansoterra
Publisher and Advertising Director: Jenny Thomas
Advertising Sales Representative: Kim Reed
Contact the Editors: To contact anyone on the IT Jungle Team
Go to our contacts page and send us a message.

Sponsored Links

Vision Solutions:  New white paper! Review the full range of Data Protection & Recovery options.
SafeData:  FREE White Paper - Best Bets for iSeries Rapid Recovery with Virtualization
Aberdeen Group:  Take the 2009 ERP in Manufacturing survey, get a free copy of complete report


 

IT Jungle Store Top Book Picks

Easy Steps to Internet Programming for AS/400, iSeries, and System i: List Price, $49.95
The iSeries Express Web Implementer's Guide: List Price, $49.95
The System i RPG & RPG IV Tutorial and Lab Exercises: List Price, $59.95
The System i Pocket RPG & RPG IV Guide: List Price, $69.95
The iSeries Pocket Database Guide: List Price, $59.00
The iSeries Pocket SQL Guide: List Price, $59.00
The iSeries Pocket Query Guide: List Price, $49.00
The iSeries Pocket WebFacing Primer: List Price, $39.00
Migrating to WebSphere Express for iSeries: List Price, $49.00
Getting Started With WebSphere Development Studio Client for iSeries: List Price, $89.00
Getting Started with WebSphere Express for iSeries: List Price, $49.00
Can the AS/400 Survive IBM?: List Price, $49.00
Chip Wars: List Price, $29.95


 
The Four Hundred
Sundry Spring Power Systems Storage Enhancements

IBM Wheels and Deals on Power 570s and 595s in Q2

Micro Focus to Buy Borland, Compuware Unit for Testing Tools

As I See It: Ah, Vacation!

Middleware Sales Are Slipping, But Could Rebound First

Four Hundred Stuff
JDA Previews New GUI for MMS at User Conference

ARCAD Moves Open Systems Initiative Forward with Application Lifecycle Management Software

Vision Updates iTERA and MIMIX for i OS HA

Key Announces GA of Smart i Appliance for BI

Oracle Refreshes JD Edwards World, Updates Tools for EnterpriseOne

Four Hundred Monitor
Four Hundred Monitor's
Full iSeries Events Calendar

System i PTF Guide
May 9, 2009: Volume 11, Number 19

May 2, 2009: Volume 11, Number 18

April 25, 2009: Volume 11, Number 17

April 18, 2009: Volume 11, Number 16

April 11, 2009: Volume 11, Number 15

April 4, 2009: Volume 11, Number 14

TPM at The Register
Rackable Systems slips into SGI's name

Fujitsu goes dense with Nehalem blades

IBM deals on big Power iron in Q2

Sun: 'We may have violated bribery laws'

Voltaire's sales plummet in Q1

US job cuts slow in April

Citrix XenServer 5.5 cleared for June landing

Moblin 2.0 Linux goes alpha (again)

Super Micro rack-mounts micro Atom server

Dell hunting M&A guru

AMD to support Intel AVX instructions

Rackable serves up $13.4m in losses

Intel animates Data Center Manager

Citrix plunks NetScaler into virtual machines

THIS ISSUE SPONSORED BY:

WorksRight Software
ProData Computer Services
Guild Companies


Printer Friendly Version


TABLE OF CONTENTS
A Not-Quite-As-Sleepy RPG Program

SQL's Other Fetch Options

Admin Alert: Four Ways To Encrypt i5/OS Backups, Part 1

Four Hundred Guru

BACK ISSUES

From the IT Jungle Forums
PHP CLI Call

Perl, PHP, and/or ZendCore

batch printing PDF files from RPG program

Using db2_connect in PHP on iSeries

How to return value from CL program?

ADO.NET/IBM.Data.DB2.iSeries/ iDB2Connection

Order by alias names




 
Subscription Information:
You can unsubscribe, change your email address, or sign up for any of IT Jungle's free e-newsletters through our Web site at http://www.itjungle.com/sub/subscribe.html.

Copyright © 1996-2009 Guild Companies, Inc. All Rights Reserved.
Guild Companies, Inc., 50 Park Terrace East, Suite 8F, New York, NY 10034

Privacy Statement