• The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
Menu
  • The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
  • Guru: SQL Writes CL

    November 30, 2020 Ted Holt

    SQL is the one tool I cannot work without. Take it away from me and I’ll start driving a truck for a living. Naturally I’m eager to find more ways to make SQL work for me. Today I’d like to share how I recently used SQL to write a huge CL command for me. This is a technique that’s good to know.

    My challenge was to copy all of the several hundred physical data files in a library to a save file so that those files could be loaded onto another IBM i system. The Save Library (SAVLIB) command was out of the question. It would have saved non-file objects, logical files, and device files. That would have greatly increased the size of the save file. The Save Object (SAVOBJ) command was exactly what I needed, as it allows up to 300 objects to be saved by one command. However, keying hundreds of physical file names would have been unwieldy, unreliable, and unreasonable, not to mention “unfun”. Fortunately, I was easily able to make SQL do the work for me. Here’s how it’s done.

    The magic begins and ends with two little words: begin and end. In between are an SQL query and a loop to process the result set. Here it is:

    begin
       declare v_Cmd     varchar(2048);
       declare v_Schema  varchar(  10)   default 'MYLIB';
       
       call qcmdexc('clrsavf mylib/mysavf');
       
       set v_Cmd = 'SAVOBJ OBJ(';
       
       for One_file as
          select t.Table_Name
            from systables as t
           where table_schema = 'MYLIB'
             and table_type = 'P'
             and file_type = 'D'
             and substr(table_name, 1, 3) <>  'SUM'
           order by table_name
       do
          set v_Cmd = v_Cmd concat ' ' concat One_file.Table_Name;
       end for;
       
       set v_Cmd = v_Cmd concat ') LIB(' concat v_Schema concat
                   ') DEV(*SAVF) OBJTYPE(*FILE) SAVF(mylib/mysavf) TGTRLS(V7R3M0) SAVACT(*LIB)';
       call systools.lprintf('v_Cmd=/' concat v_Cmd concat '/');               
       call qcmdexc (v_Cmd);
    end
    

    This is what’s known as dynamic compound statement. Mike Sansoterra introduced us to this powerful tool in this august publication a few years ago. I ran my dynamic compound statement inside the Run SQL Scripts tool within Access Client Solutions (ACS).

    Think of a dynamic compound statement as a program with no name. Like any program, it can have variables:

    declare v_Cmd     varchar(2048);
    declare v_Schema  varchar(  10)   default 'MYLIB';
    

    I follow the advice of more experienced practitioners of SQL PL and start variable names with v_. That is not a requirement.

    I have a FOR loop.

    for One_file as
       select t.Table_Name
         from systables as t
        where table_schema = 'MYLIB'
          and table_type = 'P'
          and file_type = 'D'
          and substr(table_name, 1, 3) <>  'SUM'
        order by table_name
    do
       set v_Cmd = v_Cmd concat ' ' concat One_file.Table_Name;
    end for;
    

    The FOR loop is an abbreviated form of a cursor. The SET command executes for each row of the result set and builds the list of files to be saved to the save file.

    I called QCMDEXC twice — the first time to clear the save file and the second time to execute the SAVOBJ command.

    call qcmdexc('clrsavf mylib/mysavf');
    
    set v_Cmd = 'SAVOBJ OBJ(';
    set v_Cmd = v_Cmd concat ' ' concat One_file.Table_Name;
    set v_Cmd = v_Cmd concat ') LIB(' concat v_Schema concat
      ') DEV(*SAVF) OBJTYPE(*FILE) SAVF(mylib/mysavf) TGTRLS(V7R3M0) SAVACT(*LIB)';
    call qcmdexc (v_Cmd);
    

    I also included a call to LPRINTF to write the value of v_Cmd to the job log. Since there is no object to debug, this is one way to debug a script.

    call systools.lprintf('v_Cmd=/' concat v_Cmd concat '/');               
    

    ACS has an easy way to view the job log.

    The command looked something like this:

    SAVOBJ OBJ( ACCOUNT CUSTOMER DEPT . . . YTDSLS) 
           LIB(MYLIB) 
           DEV(*SAVF) 
           OBJTYPE(*FILE) 
           SAVF(mylib/mysavf) 
           TGTRLS(V7R3M0) 
           SAVACT(*LIB
    

    And there you have it.

    Think for a moment. Thanks to Scott Forstie and his team, we have all these wonderful IBM i Services and Db2 for i Services that give us easy ways to query what’s defined to the operating system. However, these wonderful services don’t let us change what’s defined to the operating system. Do you see where I’m going with this? You can use one of those wonderful services to access data, and with a dynamic compound statement, you can build the appropriate CL command to change that data. For a one-shot task, you can’t beat it.

    If you decide that that one-shot task needs to run regularly, turning your dynamic compound statement into a permanent object is easy. Just add CREATE PROCEDURE, the appropriate parameter list, and other appropriate clauses before begin and you have a debugged stored procedure.

    create or replace procedure mylib.myproc
       (in p_Schema char(10), in p_Savf char(10), in p_SavLib char(10))
    begin
    
       declare v_Cmd     varchar(2048);
    
       call qcmdexc('clrsavf ' concat rtrim(p_SavLib) concat
                    '/' concat ltrim(p_Savf));
       
       set v_Cmd = 'SAVOBJ OBJ(';
       
       for One_file as
          select t.Table_Name
            from systables as t
           where table_schema = p_Schema
             and table_type = 'P'
             and file_type = 'D'
             and substr(table_name, 1, 3) <>  'SUM'
           order by table_name
       do
          set v_Cmd = v_Cmd concat ' ' concat One_file.Table_Name;
       end for;
       
       set v_Cmd = v_Cmd concat ') LIB(' concat p_Schema concat
                   ') DEV(*SAVF) OBJTYPE(*FILE) SAVF(' concat 
                   rtrim(p_SavLib) concat
                    '/' concat ltrim(p_Savf) concat
                    ') TGTRLS(V7R3M0) SAVACT(*LIB)';
       call qcmdexc (v_Cmd);
       
    end;
    

    A dynamic compound statement made easy work of a challenging task for me. It appears I won’t be driving a truck any time soon.

    RELATED STORIES AND RESOURCES

    Dynamic Compound Statements In DB2 For i

    SQL PL–The FOR Loop

    IBM i Services (SQL)

    Db2 for i Services

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Tags: Tags: 400guru, Access Client Solutions, ACS, CL, DB2 for i, FHG, Four Hundred Guru, IBM i, Run SQL Scripts, SQL

    Sponsored by
    WorksRight Software

    Do you need area code information?
    Do you need ZIP Code information?
    Do you need ZIP+4 information?
    Do you need city name information?
    Do you need county information?
    Do you need a nearest dealer locator system?

    We can HELP! We have affordable AS/400 software and data to do all of the above. Whether you need a simple city name retrieval system or a sophisticated CASS postal coding system, we have it for you!

    The ZIP/CITY system is based on 5-digit ZIP Codes. You can retrieve city names, state names, county names, area codes, time zones, latitude, longitude, and more just by knowing the ZIP Code. We supply information on all the latest area code changes. A nearest dealer locator function is also included. ZIP/CITY includes software, data, monthly updates, and unlimited support. The cost is $495 per year.

    PER/ZIP4 is a sophisticated CASS certified postal coding system for assigning ZIP Codes, ZIP+4, carrier route, and delivery point codes. PER/ZIP4 also provides county names and FIPS codes. PER/ZIP4 can be used interactively, in batch, and with callable programs. PER/ZIP4 includes software, data, monthly updates, and unlimited support. The cost is $3,900 for the first year, and $1,950 for renewal.

    Just call us and we’ll arrange for 30 days FREE use of either ZIP/CITY or PER/ZIP4.

    WorksRight Software, Inc.
    Phone: 601-856-8337
    Fax: 601-856-9432
    Email: software@worksright.com
    Website: www.worksright.com

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    You Can’t Just Keep Doing What You Have Always Done Breathing New Life Into Your POWER7 And POWER7+ Systems

    4 thoughts on “Guru: SQL Writes CL”

    • Les Turner says:
      December 1, 2020 at 2:02 pm

      Nice Ted! I will be using this!

      Reply
    • i-fan says:
      December 7, 2020 at 12:33 pm

      Thanks. Interesting and worth knowing, but is there an advantage to this technique compared to traditional CL?

      Reply
    • Bruce Guetzkow says:
      December 11, 2020 at 10:38 am

      Ted:
      Always a pleasure to read your articles. In response to “SQL Writes CL”, here is another way to get your list (there are always options):

      select LISTAGG(t.Table_Name,’ ‘) WITHIN GROUP(ORDER BY t.Table_Name) AS filelist
      from qsys2.systables as t
      where table_schema = ‘MYLIB’
      and table_type = ‘P’
      and file_type = ‘D’
      and substr(table_name, 1, 3) ‘SUM’

      The variable “filelist” would replace the variable “One_file.Table_Name” in the “do” loop. In fact the “do” loop would no longer be needed as “filelist” would contain the entire list. But you knew that, right? 😉

      And where did I learn about the LISTAGG function? From you, of course! (https://www.itjungle.com/2018/02/12/guru-combine-related-rows-using-sql/)

      Keep up the great work!
      Bruce

      Reply
    • Ted Holt says:
      December 13, 2020 at 8:55 pm

      You could do this task with traditional CL, i-fan. You could run DSPOBJD into an outfile. But if you want to use an SQL interface, as I did here, and as you’d do to take advantage of all those nice IBM i services and Db2 for i services, this would be the way to do it.

      Reply

    Leave a Reply Cancel reply

TFH Volume: 30 Issue: 76

This Issue Sponsored By

  • TL Ashford
  • IBM
  • UCG Technologies
  • Blair Technology Solutions
  • WorksRight Software

Table of Contents

  • How IBM i Fits Into the Evolving ERP Market
  • Breathing New Life Into Your POWER7 And POWER7+ Systems
  • Guru: SQL Writes CL
  • You Can’t Just Keep Doing What You Have Always Done
  • Resilience In The Platform, Resilience In The Business

Content archive

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

Recent Posts

  • Meet The Next Gen Of IBMers Helping To Build IBM i
  • Looks Like IBM Is Building A Linux-Like PASE For IBM i After All
  • Will Independent IBM i Clouds Survive PowerVS?
  • Now, IBM Is Jacking Up Hardware Maintenance Prices
  • IBM i PTF Guide, Volume 27, Number 24
  • Big Blue Raises IBM i License Transfer Fees, Other Prices
  • Keep The IBM i Youth Movement Going With More Training, Better Tools
  • Remain Begins Migrating DevOps Tools To VS Code
  • IBM Readies LTO-10 Tape Drives And Libraries
  • IBM i PTF Guide, Volume 27, Number 23

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