• The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
Menu
  • The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
  • Guru: Arranging Query Logic in DB2 for i Routines

    January 7, 2019 Michael Sansoterra

    Hey, Mike:

    We use a stored procedure to return the result set to Java and display the results to a screen. I would like to make this stored procedure put the result set into a temporary table and then do some processing on the temporary table. Is this possible and if so how can I achieve this? Thanks.

    Your dilemma is understandable: stored procedure result sets are great when data needs to be returned to a client. However, once generated, the result set cannot be joined, sorted, or stored in a temporary table. Thankfully, a user-defined table function (UDTF) allows a developer to perform additional operations on a query result set.

    The easiest way to accomplish this goal is to move the logic of your query from the stored procedure into a user-defined table function. Thereafter, to prevent duplicate query code, the stored procedure can be refactored to use the UDTF to build the result set for your Java program. The UDTF will provide a way to store the result set in a temporary table.

    Let’s look at a simple example. Say the below code is your stored procedure that receives a customer ID and returns a result set of customer orders (using IBM i 7.3 but it should work on earlier versions):

    CREATE OR REPLACE PROCEDURE GetOrders (@CustomerId IN INT)
    LANGUAGE SQL
    RESULT SETS 1
    NO EXTERNAL ACTION
    BEGIN
    
     DECLARE SalesOrders CURSOR FOR 
      SELECT SalesOrderId,CustomerId,
             OrderDate,ShipDate,SubTotal
        FROM SalesOrderHeader
       WHERE CustomerId=@CustomerId
    ORDER BY SalesOrderId;
    
    OPEN SalesOrders;
    
    SET RESULT SETS CURSOR SalesOrders;
    
    END;
    

    The procedure can be invoked as follows:

    CALL GetOrders (11091);
    

    The SELECT statement to build the result set contains the important logic and can be incorporated in an SQL UDTF as follows:

    CREATE OR REPLACE FUNCTION GetOrders (
    @CustomerID INT)
    RETURNS TABLE (
    SalesOrderId INT,
    CustomerId   INT,
    OrderDate    DATE,
    ShipDate     DATE,
    SUBTOTAL     DEC(19,4))
    LANGUAGE SQL
    NO EXTERNAL ACTION
    DISALLOW PARALLEL
    SET OPTION COMMIT=*NONE,USRPRF=*OWNER,DATFMT=*ISO
        RETURN
            SELECT SalesOrderId,CustomerId,
                   OrderDate,ShipDate,SubTotal
              FROM SalesOrderHeader
             WHERE CustomerId=@CustomerId
          ORDER BY SalesOrderId;
    

    Notice the SELECT statement is the same in both routines. The UDTF can be invoked as shown here and will return the same result set as the stored procedure:

    SELECT * FROM TABLE(GetOrders (11091)) Orders
    

    Now you can also create a temporary table using the function and the CREATE TABLE AS statement:

    CREATE TABLE TEMP_ORDERS AS (
    SELECT * FROM TABLE(GetOrders (11091)) Orders
    )
    WITH DATA;
    

    Just a quick word of warning, be careful about using an ORDER BY in a UDTF as it will often be ignored/overridden by a host query.

    Unless IBM changed it recently, the CREATE TABLE AS statement doesn’t support substitution parameters, so passing the customer number may require the use of EXECUTE IMMEDIATE. Here is a cheapskate example of how to do this using SQL:

    BEGIN
    
    DECLARE @SQL VARCHAR(1000);
    DECLARE @CUSTOMER_ID INT DEFAULT 11091;
    
    SET @SQL=
    'CREATE TABLE TEMP_ORDERS AS 
    (SELECT * FROM TABLE(GetOrders (' || VARCHAR(@CUSTOMER_ID) || ')) Orders) 
    WITH DATA';
    
    EXECUTE IMMEDIATE @SQL;
    
    END;
    

    Another approach to this problem that isn’t as messy as EXECUTE IMMEDIATE is to use a global variable to store the customer ID, since you can pass that variable into the function.

    Back to the task at hand, to minimize the duplication of logic and queries, you can replace the original SELECT statement in the stored procedure with a reference to the table function:

    CREATE OR REPLACE PROCEDURE GetOrders (@CustomerId IN INT)
    LANGUAGE SQL
    RESULT SETS 1
    NO EXTERNAL ACTION
    BEGIN
    
    DECLARE SalesOrders CURSOR FOR 
     SELECT Orders.*
       FROM TABLE(GetOrders(@CustomerID)) ORDERS;
    
    
    OPEN SalesOrders;
    
    SET RESULT SETS CURSOR SalesOrders;
    
    END;
    

    This technique is beneficial when code reuse is desired. However, code reuse is often harmful to performance so, depending on your situation, you may not want to adopt this approach. At the very least, a table function wrapper is going to impose some overhead on the stored procedure. But if your UDTF logic is simple and your IBM i is at i 7.2 TR4 or later, then DB2 may do you a favor and run your UDTF “inline” which should minimize the performance tax of using a UDTF.

    If for some reason your stored procedure is complicated enough so that you can’t reasonably move the code that builds the result set into a UDTF, then it is possible to build an external UDTF that wraps the stored procedure result set. The UDTF invokes the stored procedure (the opposite of what I showed above), captures and returns the result set, which allows a developer to further manipulate the data using DML. In a future tip, I will demonstrate how to create a Java UDTF wrapper to do this.

    A general design principle to take away is this: a UDTF is more versatile than a stored procedure for building result sets that may require further operations. If the performance tax is not too high and code reuse is desirable, code your result set queries in UDTFs. This specific advice only applies to building result sets; UDTFs should not necessarily be used to replace your view or materialized query table definitions!

    RELATED STORY

    Inline Table Functions In DB2 For i

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Tags: Tags: 400guru, DB2, FHG, Four Hundred Guru, IBM i, Java, SQL, UDTF, user-defined table function

    Sponsored by
    DRV Tech

    Get More Out of Your IBM i

    With soaring costs, operational data is more critical than ever. IBM shops need faster, easier ways to distribute IBM applications-based data to users more efficiently, no matter where they are.

    The Problem:

    For Users, IBM Data Can Be Difficult to Get To

    IBM Applications generate reports as spooled files, originally designed to be printed. Often those reports are packed together with so much data it makes them difficult to read. Add to that hardcopy is a pain to distribute. User-friendly formats like Excel and PDF are better, offering sorting, searching, and easy portability but getting IBM reports into these formats can be tricky without the right tools.

    The Solution:

    IBM i Reports can easily be converted to easy to read and share formats like Excel and PDF and Delivered by Email

    Converting IBM i, iSeries, and AS400 reports into Excel and PDF is now a lot easier with SpoolFlex software by DRV Tech.  If you or your users are still doing this manually, think how much time is wasted dragging and reformatting to make a report readable. How much time would be saved if they were automatically formatted correctly and delivered to one or multiple recipients.

    SpoolFlex converts spooled files to Excel and PDF, automatically emailing them, and saving copies to network shared folders. SpoolFlex converts complex reports to Excel, removing unwanted headers, splitting large reports out for individual recipients, and delivering to users whether they are at the office or working from home.

    Watch our 2-minute video and see DRV’s powerful SpoolFlex software can solve your file conversion challenges.

    Watch Video

    DRV Tech

    www.drvtech.com

    866.378.3366

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Four Hundred Monitor, January 7 LANSA Bought By Software Conglomerate Idera

    Leave a Reply Cancel reply

TFH Volume: 29 Issue: 1

This Issue Sponsored By

  • ProData Computer Services
  • iTech Solutions
  • RPG & DB2 Summit
  • Computer Keyes
  • Manta Technologies

Table of Contents

  • IBM’s Plan For Etching Power10 And Later Chips
  • LANSA Bought By Software Conglomerate Idera
  • Guru: Arranging Query Logic in DB2 for i Routines
  • Four Hundred Monitor, January 7
  • IBM i PTF Guide, Volume 20, Numbers 50 And 51

Content archive

  • The Four Hundred
  • Four Hundred Stuff
  • Four Hundred Guru

Recent Posts

  • The Power11 Transistor Count Discrepancies Explained – Sort Of
  • Is Your IBM i HA/DR Actually Tested – Or Just Installed?
  • Big Blue Delivers IBM i Customer Requests In ACS Update
  • New DbToo SDK Hooks RPG And Db2 For i To External Services
  • IBM i PTF Guide, Volume 27, Number 33
  • Tool Aims To Streamline Git Integration For Old School IBM i Devs
  • IBM To Add Full System Replication And FlashCopy To PowerHA
  • Guru: Decoding Base64 ASCII
  • The Price Tweaking Continues For Power Systems
  • IBM i PTF Guide, Volume 27, Numbers 31 And 32

Subscribe

To get news from IT Jungle sent to your inbox every week, subscribe to our newsletter.

Pages

  • About Us
  • Contact
  • Contributors
  • Four Hundred Monitor
  • IBM i PTF Guide
  • Media Kit
  • Subscribe

Search

Copyright © 2025 IT Jungle