Guild Companies, Inc.  
 
Midrange Programmer - How-To Advice & Free Code
OS/400 Edition
Volume 1, Number 9 - May 9, 2002

Dynamic Selection with Embedded SQL

by Kevin Vandever

[The code for this article is available for download.]

In "Empower Users with Embedded SQL," I showed you how to dynamically sort subfiles on any column in a subfile by embedding SQL into your RPG code and then allowing the user to select the column, or columns, by which to sort. In this article I am going to build on that application by showing you a couple of ways to dynamically filter or select the data that you want to display in your subfile.

Parameter Markers

Let's start small and work from there. First, I am going to allow the user to key a date range to shorten our Web hit list from the last article. The source code that contains this modification is webhits2.txt. Adding this to the dynamic sort doesn't seem like a big deal at first. I can use a logical view sorted by time stamp to set a lower limit at from date/time and read through the file until I reach to date/time. That's great if I always want the data sorted by time stamp, but what if I still want it sorted by user or browser? Now I'm back to using multiple logical files and negotiating my way though them to get my desired data. However, with fixed-list select statements--that is, select statements that contain a fixed number of parameters of the same data type--I can use one or more place holders (parameter markers) inside my select statement and substitute them with data at a later time, like when a user enters a date range. To do this, simply include a question mark (?) inside your select statement where your data would normally go. The following is a modified version of the SelectOne D-spec from my previous program, in the last article:

  D SelectOne    S         500A   INZ('SELECT requser, reqts,  - 
  D                               browser, UCASE(reqfile)  -     
  D                               FROM webtemp2 -                
  D                               WHERE reqts >= ?  And  -       
  D                               reqts <= ? ')

Notice that the WHERE clause states that the time stamp reqts, inside webtemp2 (to create the webtemp2 file, follow the instructions in the webtemp2_install.txt file), should be greater than or equal to some data to be determined later, and less than or equal to some other data to be determined earlier. The data to be determined later will come from the entry screen that allows the user to key in a date range. I have set defaults in the time stamps so that even if the user presses Enter without entering anything, the SQL will still contain valid from and to time stamps.

Now that the user has entered time stamps, or taken the defaults, these entries can be inserted into the select statement shown in the webhits2 source code. I do this during the opening of the cursor. Remember the PREP subroutine from my last article? This subroutine will contain a minor modification, and that modification will take place in the OPEN statement. Instead of simply opening MYCSR, I will now provide two host variables; you got it: one for each question mark (?), which will be used to insert data into my select statement. The following code snippet shows the modified OPEN statement employing the USING parameter with the from (date1) and to (date2) time stamps:

       * Open the SQL cursor.                
       *                                     
      C                                      
      C/EXEC SQL                             
      C+ OPEN MYCSR USING :date1, :date2   
      C/END-EXEC                             
       *

This minor modification to my original dynamic sorting subfile can provide your users with added flexibility without adding complicated logic to your program. For a more complicated--though more flexible--solution, let's move on.

The Where Clause

You won't always be able to use placeholders with fixed-list select statements. There may be times when you allow for optional data to be keyed. Adding to my last example a little, what if I provided capabilities to filter by user, and downloaded files but made them optional; that is, a blank entry in user field would include all users, just as a blank entry in downloaded files would include all downloaded files? In this example, webhits3.txt, depending on what was entered, your select statement will change, specifically in the WHERE clause portion of it.

The D-spec that defines my select statement, SelectOne, becomes much simpler and is built only to the lowest common denominator. The rest of the statement will be built based on what is entered on the display screen. I used this technique in the WEBHITS file from my last article to add the Order By clause, but this is a little more complex. Here is the basic select statement:

   D SelectOne    S         500A   INZ('SELECT requser, reqts,  -   
   D                               browser, UCASE(reqfile)  -       
   D                               FROM webtemp2')                    

The WHERE and ORDER BY clauses will be added to the select statement as the user enters data on the screen. It is the WHERE clause that may take many forms. If no user or downloaded file data is entered, then neither will be included in the WHERE clause. However, if either one or both were entered, they would be included. Check out the webhits3 source code, specifically the FILTER subroutine, to understand what happens whenever the Enter key is pressed on the selection screen.

The first thing the routine does is clear the WhereClause variable. Then it always performs the time stamp filter evaluation, because I always set from and to time stamp defaults. It's too much work to leave those fields blank and try to figure out if none, one, or both were entered; so I default the from time stamp to *loval and set the to time stamp to *hival. Next, the routine checks to see if something was entered in the user field. If so, then that entry is added to the WHERE clause and the list will only include user IDs matching that entry. The last thing the routine does is check to see if something was entered in the downloaded file field. If so, I want to retrieve downloaded files that contain the wildcard entered in the field. For example, if AS400 were keyed into this field, I only want to see downloaded files containing AS400 somewhere in the name.

You will notice that you have to be very specific when building a select statement this way. Everything must be exact. That is why you see the %TrimR function used to trim leading and trailing blanks, as well as the quote constant, which is declared in the D-specs, used to surround the data keyed on the screen. For flexibility, I also defined constants to hold my file field names instead of hard-coding them into the WHERE clause. Those of you who are accustomed to building complicated OPNQRYFs (Open Query Files) should have no problems with this stuff.

Filter Away

There you have it, a robust application that allows the user to both select and sort data dynamically, at their whim. Of course, there are potential performance issues if you are attacking a very large database and performing complicated selection and sorting criteria. So play with it a little and do some testing. Also, run your programs under debug and check the joblog for recommendations on permanent access path creation provided by the DB2 optimizer. This will come in handy when trying to maximize flexibility but minimize performance issues.

Sponsored By
LANSA

J.D. EDWARDS CUSTOMERS DEPLOY FAST, SECURE TRANSACTIONAL
E-BUSINESS WITH LANSA COMMERCE EDITION

Extend your J.D. Edwards system to a B2B site in just 4 to 5 weeks! JDE customers Trek Bicycle Corporation, O'Sullivan, and Echo Design have all deployed e-business solutions with LANSA. More at http://www.lansa.com/solutions/jde.htm

THIS ISSUE
SPONSORED BY:
SoftLanding Systems
LANSA
ACOM Solutions
ASNA
Profound Logic Software
WorksRight Software
BACK ISSUES
TABLE OF CONTENTS
Creating a VARPG Appointment Calendar
Dynamic Selection with Embedded SQL
Validating XML with a Document Type Definition
The Ins and Outs of Qshell
The iSeries Toolbox for Java: GUI-izing Program Calls
Exploring iSeries Navigator Application Administration
  Newsletters | Subscribe | Advertise | About Us | Contact | Search | Home  
  Last Updated: 5/8/02
Copyright © 1996-2008 Guild Companies, Inc. All Rights Reserved.