fhg
Volume 9, Number 38 -- October 21, 2009

Passing an Entire Result Set as a Parameter, Part 2

Published: October 21, 2009

by Michael Sansoterra


Note: The code accompanying this article is available for download here.


In Part 1 of this series, I discussed a generic method of passing a delimited set of text records in CSV (comma separated variable) format into a single stored procedure variable. Once the stored procedure had this text data, a generic Java user-defined table function (UDTF) was used to parse the text data and convert it to a row set that could be by any number of standard DB2 for i statements, such as a SELECT or INSERT. So with a little sweat, it is indeed possible to send multiple rows of data to a stored procedure for processing. Don't forget, this discussion of passing result sets is done in the context of client/server programming.

While adequate, this generic Java based approach suffered from a few problems:

  • All data columns within the CSV file were represented as VARCHAR(400). Columns with less data were wasting space while columns requiring a larger column size would require a slightly modified function definition.
  • All columns were generically labeled as Field1, Field2, etc.
  • Eighty columns were always returned even if they weren't needed. If you needed over 80 columns, you were out of luck.
  • Starting a Java Virtual Machine to run the function negatively impacted performance.

On the plus side, this Java UDTF could handle the majority of scenarios dealing with CSV data without changing any of the underlying code. The same cannot be said for the RPG/XML technique I will demonstrate in this tip. However, the good news is that the major performance and data typing problems mentioned above do not apply with this technique.

This tip will require the i/OS level to be at V5R4 or higher because it uses RPG's XML-INTO operation code. (For users stuck on a back-leveled OS, I did implement this technique many years back on a V5R2 system using the 5733XT1 XML Toolkit. However, it's a lot more work than using the native RPG XML support.) This tip also requires the 5722ST1 SQL Development Kit to be installed because we will be using a little embedded SQL.

The objective in this tip is still the same: we want to pass an entire set of rows in a single parameter to a stored procedure where the parameter is converted into a set of rows that can be used by DB2 for i SQL statements. This time, instead of using the CSV text format we'll use XML. For the sake of illustration, we'll stick with implementing the solution using an RPG UTDF, although an RPG program using this same technique could also serve just as well as a standalone stored procedure with the advantage of better performance.

In the first tip, the sample data had three pieces of information: GL Account Number, Debit value, and Credit value. We can represent the same information as an XML definition as follows:

<JrnlLines>
<JrnlLine>
    <Account>100020</Account>
    <Debit>0</Debit>
    <Credit>1007.95</Credit>
</JrnlLine>
<JrnlLine>
    <Account>100030</Account>
    <Debit>1007.95</Debit>
    <Credit>0</Credit>
</JrnlLine>
</JrnlLines>

Assuming the client-side program can package XML data in this manner, it's a snap to have RPG read the XML into a data structure array. With the XML-INTO op-code, the XML text is shredded and put into a data structure array with one C-Spec!

RPG program GETJRNDTA acts as a UDTF to transform an XML fragment into a result set with these steps:

  1. Receive a large character parameter as a LOB locator (a locator is a special SQL "pointer" that references a large object type such as a BLOB, CLOB, or DBCLOB).
  2. Take the XML data chunk by chunk from the CLOB and load it into an RPG string variable.
  3. Let the RPG XML-INTO program convert the XML data into a data structure array.
  4. Extract the data from the data structure one row at a time and give it back to DB2.
  5. Clean up the locator when finished.

Once the RPG program GETJRNDTA is compiled, it must be registered for use with SQL using the CREATE FUNCTION statement as follows:

Create Function xxxxx/GETJRNDTA
(XMLData Clob(2M) As Locator)   /* Use Clob(64K) for V5R4 */
Returns Table
(Account Char(20), 
 Debit   Dec(9,2),
 Credit  Dec(9,2))
External
Language RPGLE
Disallow Parallel
Modifies SQL Data
Parameter Style DB2SQL
Not Fenced

In case you're not familiar with UDTF functions, they are simply a special program that gathers data in a tabular (row and column) format for use with DB2. In this case, RPG table function GetJrnDta will take the above XML fragment and convert it to a set of rows:


Account

Debit

Credit

100020

0

1007.95

100030

1007.95

0


Here's a sample of how the RPG program would be invoked by DB2 as a table function in a query:

Select * 
  From Table(GetJrnDta('
<JrnlLines>
<JrnlLine>
    <Account>100020</Account>
    <Debit>0</Debit>
    <Credit>1007.95</Credit>
</JrnlLine>
<JrnlLine>
    <Account>100030</Account>
    <Debit>1007.95</Debit>
    <Credit>0</Credit>
</JrnlLine>
</JrnlLines>')) JournalEntries

Of course, in a client/server environment the XML data would be passed as a parameter to the table function or to a stored procedure that invoked the table function instead of having hard-coded text as illustrated above.

Here is a simple stored procedure that accepts the XML data as a CLOB parameter and uses the GetJrnDta UDTF to convert the XML data into rows:

Create Procedure xxxxx/ProcessJournalEntry
(XMLData In CLOB(2M))
Language SQL
Set Option Commit=*None, UsrPrf=*Owner, DatFmt=*ISO
Begin
    Declare Debits  Dec(11,2) Not Null Default 0;
    Declare Credits Dec(11,2) Not Null Default 0;

    Select Sum(Debit),Sum(Credit)
      Into Debits, Credits
      From Table(GetJrnDta(XMLData)) BalanceCheck;

    If Debits<>Credits Then
        Signal SQLSTATE '38I01'
           Set Message_Text='Debits Must Equal Credits';
    End If;

-	- Do more stuff here...
    Insert Into QTEMP.JournalEntry
    Select *
      From Table(GetJrnDta(XMLData)) JournalData;

End; '

Before I end, there are a few things to note about the RPG function:

  • When passing large XML strings into a stored procedure, it may be quicker to immediately dump the data into a DB2 temporary table for subsequent processing rather than invoking the table function multiple times because table functions are relatively slow.
  • I wrote the RPG program the "easy way" by assuming the XML data would be 64K or less on a V5R4 system or 16MB or less on a V6R1 (a.k.a. 6.1) i/OS system (each maximum being the respective maximum RPG character variable lengths.) The XML-SAX operation code allows for processing larger XML documents piece by piece but the programming is more intricate. With the V5R4 program however, the original requirement of allowing up to 9,999 rows be passed back is not permissible using my "el-cheap-o" method, due to the 64K string length barrier.

Finally, passing XML data in a CLOB variable is an excellent way to pass and process a set of rows in a stored procedure. Thanks to the XML-INTO operation code, RPG is a great language choice for easily parsing XML into a useable form. Any errors encountered while parsing the XML data can be handled by the RPG program. Further, when creating a table function, using XML and RPG allows the data to be returned to DB2 as a strongly typed result set.


Michael Sansoterra is a programmer/analyst for i3 Business Solutions, an IT services firm based in Grand Rapids, Michigan. Send your questions or comments for Mike to Ted Holt via the IT Jungle Contact page.


RELATED STORY

Passing an Entire Result Set as a Parameter: Part 1



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


Sponsored By
PRODATA COMPUTER SERVICES

Create your own stimulus package!

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 $500!
www.prodatacomputer.com
800.228.6318


Senior Technical Editor: Ted Holt
Technical Editor: Joe Hertvik
Contributing Technical Editors: Erwin 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

Infor:  Visit the first System i Virtual Conference hosted by Infor and IBM. View on-demand Webinar.
CCSS:  Need Pro-Active Management of Your IBM® i Server? We can help.
Patrick Townsend Security Solutions:  Get a customized state privacy law compliance 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
IBM Dynamic Infrastructure Announcements Due October 20

Steady as She Goes for IBM's Third Quarter

IBM i Access to Support Windows 7 on December 1

Mad Dog 21/21: Oy, Cloudy Us!

IBM Slashes i Compiler and Rational Tool Prices

Four Hundred Stuff
Jarman Flashes Clues on Future DB2 and RPG Directions

i365 Launches New EVault Backup Appliance, Cloud Storage Service

nuBridges Delivers Major Upgrade to MFT Solution

Info Builders Prophesizes World Series Winner with Predictive Analytics

Oracle Encourages JD Edwards Customers to Hang Tight

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

System i PTF Guide
October 17, 2009: Volume 11, Number 42

October 10, 2009: Volume 11, Number 41

October 3, 2009: Volume 11, Number 40

September 26, 2009: Volume 11, Number 39

September 19, 2009: Volume 11, Number 38

September 12, 2009: Volume 11, Number 37

September 5, 2009: Volume 11, Number 36

TPM at The Register
Gartner: IT spending growth next year

BMC eats Tideway for discovery tools

IBM installs temp server GM after insider trading furore

Boffins fawn over dirt cheap server clusters

Ellison whips out his Sparc TPC-C test

Sun tunes its VirtualBox

IBM, Intel execs arrested over alleged insider trading

US boffins use Obama dough to study clouds

IBM: Power7 to rollout throughout 2010

HP peddles app stress-testing cloud

IBM wrings more profits out of declining Q3

Oracle revs Xen VM to 2.2

THIS ISSUE SPONSORED BY:

Halcyon Software
ProData Computer Services
Twin Data


Printer Friendly Version


TABLE OF CONTENTS
Getting the Message, Part 2

Passing an Entire Result Set as a Parameter, Part 2

Setting Up SNTP Time Synchronization on an i5/OS Box

Four Hundred Guru

BACK ISSUES




 
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