25
Mon, Nov
1 New Articles

APIs That Sort

APIs
Typography
  • Smaller Small Medium Big Bigger
  • Default Helvetica Segoe Georgia Times

Just because RPG doesn’t have native data sorting functions, it does not mean that RPG can’t sort data. In fact, as soon as you learn how to use these sorting APIs with RPG, you may forget that RPG could never really sort data in the first place!

Data structures and files can be sorted on the AS/400 in different ways. One interesting method entails the use of the QLGSORT (Sort) and QLGSRTIO (Sort Input/Output) APIs. These APIs are quite efficient and can be called from any AS/400 high-level language (HLL) program, such as RPG III, RPG IV, ILE COBOL, Original Program Model (OPM) COBOL, and ILE C. Using these APIs in your programs enables you to do the following from within an HLL program:

• Sort an area of memory, such as an RPG multiple-occurrence data structure (MODS), within a HLL program

• Sort up to 32 input files and produce from one to 32 output files
• Sort data with an alternae collating sequence
• Sort data by natural language sequences (coded character set ID or CCSIDs) This article explains and demonstrates how QLGSORT and QLGSRTIO work. Read on and learn how to add these powerful sorting techniques to your programming toolbox.

Using QLGSORT and QLGSRTIO

QLGSORT makes a single dynamic call from inside your HLL to sort data stored either in an input buffer or in physical files. QLGSRTIO can be used either to provide a set of records or return a set of records that has already been sorted. To do the latter, a sort initialization call to QLGSORT must first be issued. Both of these APIs use complex data structures, so it’s a good idea to review IBM’s documentation about them. (Documentation on using QLGSORT and QLGSRTIO is provided in the OS/400 National Language Support APIs manual.)

On my system, the data structures required by QLGSORT and QLGSRTIO are contained in the QRPGLESRC source file, located in the IBM-supplied QSYSINC library.

The IBM documentation mentioned provides no practical examples, but this article does. Because of spatial considerations, however, entire programming examples are not published. Still, critical code excerpts are illustrated thoroughly. The entire source code for the examples is available free of charge from the Midrange Computing Web site at www.midrangecomputing.com/mc/99/04.

Yes, Virginia, You Can Sort a Multiple-Occurrence Data Structure

To sort a file, you use OPNQRYF, FMTDTA, or even RGZPFM; to sort an array in RPG, use SORTA. And to sort a MODS, use QLGSORT; I’ve even written an RPG IV program called SrtMODSPrn that shows you how.

Figure 1 displays the parameters used by QLGSORT. Data structures and variables used as parameters for QLGSORT are illustrated in Figure 2. The MODS that I am sorting is a simple employee list that my program calls EmpRecord (see Figure 2). The sort specified is by last name and then by first name, in ascending order. SrtMODSPrn first prints the unsorted MODS, and after QLGSORT is called, it prints the sorted MODS (see Figure 3). Now, let’s take a closer look at how this is done.

First, SrtMODSPrn loads EmpRecord with five sets of arbitrary name values, all of which are printed. Next, SrtMODSPrn uses subroutine ExecSort to set up the QLGSORT Sort control block (SrtCtlBlk) and two key values, SrtKeyLst1 and SrtKeyLst2. Then, a call to QLGSORT is issued using the correct parameters. The code fragment containing the critical portions of ExecSort is depicted in Figure 4.

I developed SrtCtlBlk based on the IBM-supplied data structures in my system. All values were initially set at 0, and most will remain that way. I will focus on those values that are changed and why. The new values for those variables and reasons for their assignments are as follows:

• ReqTyp, which is the requested type, is set at 5. According to IBM documentation, when an input data buffer and output data buffer are used, 5 is the value of the requested type.

• RecLen, the record length, is set at 50 because that is the length of the EmpRecord MODS.

• RecCount represents record count. It is assigned a value of 5 because that is the number of occurrences for the EmpRecord MODS.

• OffKeyLst represents the offset of the key list and is set at 80, the length of SrtCtlBlk up to the point where SortKeyVals is declared.

• NumKeys, which is the number of keys, is set at 2 (LastName and FirstName).
• LenKeyEnt is length of the key entry and is assigned a value of 16, the length of SortKeyVals in data structure SrtCtlBlk.

• LenSrtSeq is the length of the national sort sequence information. Its minimum length must be 290.

• LenBlk is the length of the request control block. My program represents this with the sum of 80, 16, and 16. 80 is the length of my Sort control block (SrtCtlBlk), and 16 is the length of both the first (SrtKeyLst1) and second (SrtKeyLst2) keys. (Of course, I could have specified 112, but I wanted to explain how the number is derived.)

• SrtMODSLen stands for the length of my EmpRecord MODS. My program represents this number as 5 multiplied by 50 because EmpRecord has a length of 50 in 5 occurrences.

• KeyStrPos1 is the starting position for my first key, LastName; its value is 21.
• StringSiz1 is the length of LastName and has a value of 30.
• DataType1 is the key data type for LastName. Per IBM documentation, when the data type is a character, the value is 6. There are 23 different key data types, including zoned decimals, packed decimals, dates, and times.

• SortOrder1 is the sort order of LastName. For ascending values, this value is 1. If it were descending, the value would be 2.

• KeyStrPos2 is the starting position for my second key, FirstName. This value is

1.

• StringSiz2 is the length of FirstName and has a value of 20.
• DataType2 is the key data type for FirstName, with a value of 6.
• SortOrder2 is the sort order of LastName. The order is ascending, so the value is Immediately after all these values are set, QLGSORT is ready to be called using the required parameter set. Once again, these parameters are Sort control block (SrtCtlBlk), Input MODS (EmpRecord), Output MODS (EmpRecord), Input MODS length (SrtMODSLen), Output MODS length (SrtMODSLen), and Standard API error data structure (APIErr). When QLGSORT is called, my sorted MODS is returned, and the results are printed (Figure 3).

Now, let’s examine how QLGSRTIO is used.

Putting Sorted Data into Physical Files, QLGSRTIO Style

As previously mentioned, in order to execute QLGSRTIO properly, you must first use QLGSORT to execute a sort initialization call. My next example program, SrtMODSFil, is designed to be as close as possible to my first example program. Because it uses QLGSORT to initialize the sorting process, we continue to use SrtCtlBlk.

By the same token, because we use QLGSRTIO, we need some new variables, data structures, and parameters. The required parameter list for QLGSRTIO is displayed in Figure 5, and the additional data structures and variables to be used by the QLGSRTIO program calls are displayed in Figure 6.

The first data structure displayed in Figure 6 is named SrtIOCtl and serves as my Sort control block for QLGSRTIO. The next data structure is named EmpRecord1 and is used in conjunction with my EmpRecord MODS. The standalone variables are OutSizeLen, FillerParm, and InSizeLen. InSizeLen and OutSizeLen are used to compute record lengths, while FillerParm is used when necessary as a filler parameter value.

In my example program, after the MODS is loaded, QLGSORT is called using SrtCtlBlk, InSizeLen, and OutSizeLen as the critical parameters. This operation is performed in subroutine ExecSort, displayed in Figure 7. When QLGSORT is called, the SrtCtlBlk values are almost the same as before. The only notable difference is that the record count (RecCount) value is set at 0. Parameters InSizeLen and OutSizeLen are computed by QLGSORT and used later by QLGSRTIO during subsequent calls.

The first call to QLGSRTIO loads the MODS values into the QLGSRTIO input buffer via EmpRecord. To execute this operation, the request type value SrtIOTyp is set at
1. The value 1 represents the “Put” function for QLGSRTIO. After the QLGSRTIO buffer loading operation has been completed, the sort operation is ready to be executed. This is accomplished by setting the value of SrtIOTyp to 2, which represents the “End Put” function for QLGSRTIO. QLGSRTIO is called again, and the input buffer is sorted.

The final series of calls to QLGSRTIO is to return the data buffer to my HLL program via the output parameter (EmpRecord1). For this operation, the value of SrtIOTyp is set at 3, the “Get” function for QLGSRTIO. This operation is accomplished one record at a time until the process is complete. When the value of EmpRecord1 returns to SrtMODSFil, the values are moved to the physical file fields and the record is written to the file. The final result is that the output of the sorted MODS is saved in the file and the program terminates.

At this point, you can see the importance of these repetitive calls to QLGSRTIO. Especially important is setting the correct request type because data loaded into the QLGSRTIO buffers stays there until the next call. In order to clear and delete the buffers, you should specify 4 as the value of the request type when calling QLGSRTIO. This invokes QLGSRTIO’s “Cancel” function.

Implementing Sort APIs with AS/400 Applications


1.

Some HLLs, such as COBOL, have very specialized commands that can be used for sorting data in data structures or files. Other languages, such as RPG, are not so developed in this regard. The Sort APIs are a great way to get around this limitation. Honestly, when I learned how to use these APIs, I wished that I had learned them earlier. It would have saved me quite a bit of work, and my programs would have run quicker.

I have shared this knowledge with other programmers who have found it very useful. I hope that you have found it useful as well.

Reference

OS/400 National Language Support APIs V4R2 (SC41-5863-01, CD-ROM QB3AMO01)

Required Parameter Group:

Order Description Usage Type

1 Request control block Input Char(*)
2 Input data buffer Input Char(*)
3 Output data buffer Output Char(*)
4 Length of output data buffer Input Binary(4)
5 Length of returned data Output Binary(4)
6 Error code Output Char(*)

Optional Parameter Group :

7 Returned records feedback Output Char(*)
8 Length of returned records feedback Input Binary(4)

*================================================================

* Employee List to be sorted by LastName, FirstName

D EmpRecord ds occurs(05)

D FirstName 20a

D LastName 30a

*================================================================

D SrtMODSLen s 4b 0

*================================================================

D* QLGSORT Sort Control Block

D SrtCtlBlk DS

D* Length Block

D LenBlk 1 4B 0 inz(0)

D* Request Type

D ReqTyp 5 8B 0 inz(0)

D* Reserved1

D Reserved1 9 12B 0 inz(0)

D* Options

D Options 13 16B 0 inz(0)

D* Record Length

D RecLen 17 20B 0 inz(0)

D* Record Count

D RecCount 21 24B 0 inz(0)

D* Offset Key List

D OffKeyLst 25 28B 0 inz(0)

D* Number Keys

D NumKeys 29 32B 0 inz(0)

D* Offset Lang Info

D OffLangInf 33 36B 0 inz(0)

D* Offset Input List

D OffInLst 37 40B 0 inz(0)

D* Number Input Files

D NumInFils 41 44B 0 inz(0)

D* Offset Output List

D OffOutLst 45 48B 0 inz(0)

D* Number Output Files

D NumOutFil 49 52B 0 inz(0)

D* Length Key Entry

D LenKeyEnt 53 56B 0 inz(0)

D* Length Sort Seq

D LenSrtSeq 57 60B 0 inz(0)

D* Length Infile Entry

D LenInFile 61 64B 0 inz(0)

D* Length Outfile Entry

D LenOutFile 65 68B 0 inz(0)

D* Offset Null Map

Figure 1: QLGSORT uses this parameter list.

D OffNullMap 69 72B 0 inz(0)

D* Offset Record Info

D OffRecInf 73 76B 0 inz(0)

D* Reserved2

D Reserved2 77 80B 0 inz(0)

D* Key Definition for the 2 QLGSORT keys

D SortKeyVals 16A dim(2)

*================================================================

D* First Sort Key Definition

D SrtKeyLst1 DS

D* Start Position1

D KeyStrPos1 1 4B 0

D* String Size1

D StringSiz1 5 8B 0

D* Data Type1

D DataType1 9 12B 0

D* Sort Order1

D SortOrder1 13 16B 0

*================================================================

* Second Sort Key Definition

D SrtKeyLst2 DS

D* Start Position2

D KeyStrPos2 1 4B 0

D* String Size2

D StringSiz2 5 8B 0

D* Data Type2

D DataType2 9 12B 0

D* Sort Order2

D SortOrder2 13 16B 0

*================================================================

* Subroutine ExecSort will setup the sort control block and

* sort keys. Then QLGSORT will be called.

*

C ExecSort begsr

* Setup QLGSORT Control Block

C eval ReqTyp = 5

C eval RecLen = 50

C eval RecCount= 5

C eval OffKeyLst = 80

C eval NumKeys = 2

C eval LenKeyEnt = 16

C eval LenSrtSeq = 290

C eval LenBlk = 80 + 16 + 16

C eval SrtMODSLen = 5 * 50

* Setup QLGSORT Sort Keys

C eval KeyStrPos1 = 21

C eval StringSiz1= 30

C eval DataType1 = 6

C eval SortOrder1 = 1

*

C eval KeyStrPos2 = 1

C eval StringSiz2 = 20

C eval DataType2 = 6

C eval SortOrder2 = 1

* Move keys to control block

C eval SortKeyVals(1) = SrtKeyLst1

C eval SortKeyVals(2) = SrtKeyLst2

* Execute QLGSORT

C call 'QLGSORT'

C parm SrtCtlBlk

Figure 2: The QLGSORT API requires that certain information be provided in data structures.

Personnel Listing

- Unsorted
First Name Last Name
Joseph Zimmerman
Laura Sanderson
Andrew Sanderson
Alice Sanderson
Frank Anderson Personnel Listing

- Sorted by Last, First Name
First Name Last Name
Frank Anderson
Alice Sanderson
Andrew Sanderson
Laura Sanderson
Joseph Zimmerman

Figure 3: The output of program SrtMODSPrn shows both unsorted and sorted data.

C parm EmpRecord

C parm EmpRecord

C parm SrtMODSLen

C parm SrtMODSLen

C parm APIErr Required Parameter Group:

Order Description Usage Type

1 Request control block Input Char(16)
2 Input data buffer Input Char(*)
3 Output data buffer Output Char(*)
4 Length of output data buffer Input Binary(4)
5 Output data information Output Binary(4)
6 Error code I/O Char(*)

Optional Parameter Group:

7 Returned records feedback Output Char(*)
8 Length of returned records feedback Input Binary(4)

*================================================================

D* QLGSRTIO Sort Control Block

D SrtIOCtl DS

D* Sort IO Request Type

D SrtIOTyp 1 4B 0

D* Sort IO Reserved Field

D SrtIORsrv 5 8B 0

D* Sort IO Record Length

D SrtIORLen 9 12B 0

D* Sort IO Record Count

D SrtIORCnt 13 16B 0

*================================================================

D EmpRecord1 ds

D FirstName1 20a

D LastName1 30a

* Employee List to be sorted by LastName, FirstName

D EmpRecord ds occurs(05)

D FirstName 20a

D LastName 30a

*================================================================

D SrtMODSLen s 4b 0

D OutSizelen s 9b 0

D FillerParm s 16a

D InSizelen s 9b 0

*================================================================

* Subroutine ExecSort will setup the sort control block and

* sort keys. Then QLGSORT will be called.

*

C ExecSort begsr

* Setup QLGSORT Control Block

C eval RecLen = 50

C eval RecCount= 0

C eval OffKeyLst = 80

C eval NumKeys = 2

C eval LenKeyEnt = 16

C eval LenSrtSeq = 290

C eval LenBlk = 80 + 16 + 16

C eval SrtMODSLen = 50 * 5

* Setup QLGSORT Sort Keys

C eval KeyStrPos1 = 21

C eval StringSiz1= 30

C eval DataType1 = 6

C eval SortOrder1 = 1

*

C eval KeyStrPos2 = 1

C eval StringSiz2 = 20

C eval DataType2 = 6

C eval SortOrder2 = 1

Figure 4: Setting up and calling QLGSORT is a matter of initializing data structures with the proper values.

Figure 5: The QLGSRTIO API uses this parameter list.

Figure 6: Sorting files with QLGSRTIO API requires additional data structures.

* Move keys to control block

C eval SortKeyVals(1) = SrtKeyLst1

C eval SortKeyVals(2) = SrtKeyLst2

* Execute QLGSORT initialization call

C call 'QLGSORT'

C parm SrtCtlBlk

C parm FillerParm

C parm FillerParm

C parm InSizelen

C parm OutSizelen

C parm APIErr

...

*

* Execute QLGSRTIO Call #1, by loading five records at once

C clear SrtIOCtl

C eval SrtIORLen = 50

C eval SrtIORCnt = 5

C eval SrtIOTyp = 1

*

C call 'QLGSRTIO'

C parm SrtIOCtl

C parm EmpRecord

C parm FillerParm

C parm InSizelen

C parm FillerParm

C parm APIErr

...

*

* Execute QLGSRTIO Call#2, to perform actual sort

C clear SrtIOCtl

C eval SrtIOTyp = 2

C eval SrtIORLen = 50

C eval SrtIORCnt = 5

C call 'QLGSRTIO'

C parm SrtIOCtl

C parm EmpRecord

C parm FillerParm

C parm InSizelen

C parm FillerParm

C parm APIErr

....

*

* Execute final QLGSRTIO Call #3, to return records one at a time

* After records are returned they are written to the outfile

C clear SrtIOCtl

C eval SrtIOTyp = 3

C eval SrtIORLen = 50

C eval SrtIORCnt = 1

C eval OccurIdx = 1

C do 5 OccurIdx

C call 'QLGSRTIO'

C parm SrtIOCtl

C parm FillerParm

C parm EmpRecord1

C parm SrtIORLen

C parm FillerParm

C parm APIErr

...

*

C eval SFirstNam = FirstName1

C eval SLastNam = LastName1

C write SrtOutR

C enddo

C endsr

Figure 7 : This code illustrates how you can return sorted data into a file from within RPG.

BLOG COMMENTS POWERED BY DISQUS

LATEST COMMENTS

Support MC Press Online

$

Book Reviews

Resource Center

  • SB Profound WC 5536 Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application. You can find Part 1 here. In Part 2 of our free Node.js Webinar Series, Brian May teaches you the different tooling options available for writing code, debugging, and using Git for version control. Brian will briefly discuss the different tools available, and demonstrate his preferred setup for Node development on IBM i or any platform. Attend this webinar to learn:

  • SB Profound WP 5539More than ever, there is a demand for IT to deliver innovation. Your IBM i has been an essential part of your business operations for years. However, your organization may struggle to maintain the current system and implement new projects. The thousands of customers we've worked with and surveyed state that expectations regarding the digital footprint and vision of the company are not aligned with the current IT environment.

  • SB HelpSystems ROBOT Generic IBM announced the E1080 servers using the latest Power10 processor in September 2021. The most powerful processor from IBM to date, Power10 is designed to handle the demands of doing business in today’s high-tech atmosphere, including running cloud applications, supporting big data, and managing AI workloads. But what does Power10 mean for your data center? In this recorded webinar, IBMers Dan Sundt and Dylan Boday join IBM Power Champion Tom Huntington for a discussion on why Power10 technology is the right strategic investment if you run IBM i, AIX, or Linux. In this action-packed hour, Tom will share trends from the IBM i and AIX user communities while Dan and Dylan dive into the tech specs for key hardware, including:

  • Magic MarkTRY the one package that solves all your document design and printing challenges on all your platforms. Produce bar code labels, electronic forms, ad hoc reports, and RFID tags – without programming! MarkMagic is the only document design and print solution that combines report writing, WYSIWYG label and forms design, and conditional printing in one integrated product. Make sure your data survives when catastrophe hits. Request your trial now!  Request Now.

  • SB HelpSystems ROBOT GenericForms of ransomware has been around for over 30 years, and with more and more organizations suffering attacks each year, it continues to endure. What has made ransomware such a durable threat and what is the best way to combat it? In order to prevent ransomware, organizations must first understand how it works.

  • SB HelpSystems ROBOT GenericIT security is a top priority for businesses around the world, but most IBM i pros don’t know where to begin—and most cybersecurity experts don’t know IBM i. In this session, Robin Tatam explores the business impact of lax IBM i security, the top vulnerabilities putting IBM i at risk, and the steps you can take to protect your organization. If you’re looking to avoid unexpected downtime or corrupted data, you don’t want to miss this session.

  • SB HelpSystems ROBOT GenericCan you trust all of your users all of the time? A typical end user receives 16 malicious emails each month, but only 17 percent of these phishing campaigns are reported to IT. Once an attack is underway, most organizations won’t discover the breach until six months later. A staggering amount of damage can occur in that time. Despite these risks, 93 percent of organizations are leaving their IBM i systems vulnerable to cybercrime. In this on-demand webinar, IBM i security experts Robin Tatam and Sandi Moore will reveal:

  • FORTRA Disaster protection is vital to every business. Yet, it often consists of patched together procedures that are prone to error. From automatic backups to data encryption to media management, Robot automates the routine (yet often complex) tasks of iSeries backup and recovery, saving you time and money and making the process safer and more reliable. Automate your backups with the Robot Backup and Recovery Solution. Key features include:

  • FORTRAManaging messages on your IBM i can be more than a full-time job if you have to do it manually. Messages need a response and resources must be monitored—often over multiple systems and across platforms. How can you be sure you won’t miss important system events? Automate your message center with the Robot Message Management Solution. Key features include:

  • FORTRAThe thought of printing, distributing, and storing iSeries reports manually may reduce you to tears. Paper and labor costs associated with report generation can spiral out of control. Mountains of paper threaten to swamp your files. Robot automates report bursting, distribution, bundling, and archiving, and offers secure, selective online report viewing. Manage your reports with the Robot Report Management Solution. Key features include:

  • FORTRAFor over 30 years, Robot has been a leader in systems management for IBM i. With batch job creation and scheduling at its core, the Robot Job Scheduling Solution reduces the opportunity for human error and helps you maintain service levels, automating even the biggest, most complex runbooks. Manage your job schedule with the Robot Job Scheduling Solution. Key features include:

  • LANSA Business users want new applications now. Market and regulatory pressures require faster application updates and delivery into production. Your IBM i developers may be approaching retirement, and you see no sure way to fill their positions with experienced developers. In addition, you may be caught between maintaining your existing applications and the uncertainty of moving to something new.

  • LANSAWhen it comes to creating your business applications, there are hundreds of coding platforms and programming languages to choose from. These options range from very complex traditional programming languages to Low-Code platforms where sometimes no traditional coding experience is needed. Download our whitepaper, The Power of Writing Code in a Low-Code Solution, and:

  • LANSASupply Chain is becoming increasingly complex and unpredictable. From raw materials for manufacturing to food supply chains, the journey from source to production to delivery to consumers is marred with inefficiencies, manual processes, shortages, recalls, counterfeits, and scandals. In this webinar, we discuss how:

  • The MC Resource Centers bring you the widest selection of white papers, trial software, and on-demand webcasts for you to choose from. >> Review the list of White Papers, Trial Software or On-Demand Webcast at the MC Press Resource Center. >> Add the items to yru Cart and complet he checkout process and submit

  • Profound Logic Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application.

  • SB Profound WC 5536Join us for this hour-long webcast that will explore:

  • Fortra IT managers hoping to find new IBM i talent are discovering that the pool of experienced RPG programmers and operators or administrators with intimate knowledge of the operating system and the applications that run on it is small. This begs the question: How will you manage the platform that supports such a big part of your business? This guide offers strategies and software suggestions to help you plan IT staffing and resources and smooth the transition after your AS/400 talent retires. Read on to learn: