04
Mon, Nov
6 New Articles

TechTalk

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

Discover the Error of Your Ways

Q: How does a program determine errors after calling a UNIX-type API?

— Gene Gaunt This email address is being protected from spambots. You need JavaScript enabled to view it.

A: The code in Figure 1 shows how to retrieve the error value when calling UNIX-type APIs.

— Carsten Flensburg This email address is being protected from spambots. You need JavaScript enabled to view it.

H debug

D errno Pr 10i 0

D strerror Pr 128A

**

D fclose Pr extproc('fclose')

D parm * value

D errnbr s 10i 0

D errtxt s 46A noopt

**

C callp fclose (*NULL)

C eval errnbr = errno

C errnbr dsply

C eval errtxt = strerror

C errtxt dsply

C dump

**

C seton lr

**

P errno B

D errno Pi 10I 0

D sys_errno Pr * ExtProc('__errno')

D errnbr S 10I 0 Based(errptr)

D errptr S *

**

C Eval errptr = sys_errno

C Return errnbr

**

P E

**

P strerror B

D strerror Pi 128A

D sys_strerror Pr * ExtProc('strerror')

D 10I 0 Value

D errtxt S 128A Based(txtptr) Noopt

Figure 1: This code fragment finds the error value when you call UNIX-type APIs.

Don’t Be So Quick to Pull the Trigger

Many AS/400 programmers have taken advantage of database triggers to let OS/400 protect their data integrity. For example, they use triggers to validate data when a record is added and to ensure that, if a record is deleted, any other business rules that should be in effect for related records are also enforced. For the most part, this technique works great. However, there is at least one instance when database triggers cannot protect your data. If someone runs Clear Physical File Member (CLRPFM) over a database file being protected by a trigger, that trigger is not fired, because triggers act at the row level, not the file level. That is, the trigger is not activated unless the deletion is performed one row at a time (for example, using the DELETE operation in RPG or pressing F23, the Delete function key, while in the DFU).

— Chuck Pence This email address is being protected from spambots. You need JavaScript enabled to view it.

Changing the Code Page of AS/400 IFS Files

For those who have used a PC-based tool such as Microsoft Word or Excel or Lotus 1-2-3 to view the contents of an AS/400 Integrated File System (AS/400 IFS) file created using Copy to Import File (CPYTOIMPF), the file probably appeared to contain gibberish. This was probably because the PC-based program expected the file to be ASCII and the file contained EBCDIC characters. One way to remedy this is to set the code page of the AS/400 IFS files to ASCII before using CPYTOIMPF to load the file with data. This translates the data being placed in the file to ASCII. Follow these six steps to create an ASCII code page AS/400 IFS file that can be used as a base to set the code page of new AS/400 IFS files:

1. CRTPF lib/temp rcdlen(1) (Add a record to this file by using a utility program such as DFU.)

2. CD DIR(‘/qdls/foldername’)

3. CPYTOIMPF FILE(lib/temp) TOSTMF(‘temp’) RCDDLM(*CRLF)

4. MOV OBJ(‘temp’) TOOBJ(‘CCSID00367’) TOCODEPAGE(00367)

5. Copy the ASCII code page file to create the output AS/400 IFS file for your CPYTOIMPF command when you first use an output AS/400 IFS file. Issue the following command to replace myASCIIfile.csv with the name of the file you are specifying on the CPYTOIMPF command:

CPY OBJ(‘CCSID00367’) TOOBJ(‘myASCIIfile.csv’)

When you specify your new AS/400 IFS file on the CPYTOIMPF command, the data is translated to ASCII as it is copied to the output AS/400 IFS file.

6. CPYTOIMPF FILE(lib/file) TOSTMF(‘myASCIIfile.csv’) RCDDLM(*CRLF) REPLACE(*YES)

— David Morris This email address is being protected from spambots. You need JavaScript enabled to view it.

What’s the Deal with INST?

Q: How do you map to a source line number from a job log’s INST column? I know the INST number is hexadecimal. However, I think the hexadecimal number is not a source line number but a compile listing STMT number. I used the Win95 calculator (in Scientific view) to enter the hexadecimal number to convert it to decimal. I then compiled the source to get the STMT numbers, making sure the source change date and time agreed with the program object. I knew I was looking for some kind of I/O function, because the job log message I was trying to track down was about a record lock, but the steps I took did not get me to an I/O source line. The program was not ILE, and the default GENOPT option *NOOPTIMIZE was used.

— Paul Roubekas This email address is being protected from spambots. You need JavaScript enabled to view it.

A: Here’s one method you can use. The INST column in the job log shows MI statement numbers. Follow these steps to determine the SEU line number:
1. Recompile the program and specify GENOPT(*LIST).
2. Look near the end of the compiler listing for a section of MI code. Look for the INST column, the second column from the left. Find the number in this column that appears in your job log.
3. Look in the far left column on the line matching your instruction number. This is the SEU line number (e.g., 12300).

— Gene Gaunt This email address is being protected from spambots. You need JavaScript enabled to view it.

Editor’s Note: Of course, you could always just look at the job log. It specifies the line number in error in the message text.

Finding Numeric Values in Packed Fields

Q: I have a program that writes to and updates packed decimal fields. Because of the way the program is structured, I’m not always sure that the data going into that field is valid for the data type. When invalid data goes into the field, it causes problems, such as decimal data errors if other programs try to access the data in that field. Is there a method I can use to test for valid data in packed decimal fields before I write it to a file?

— Edwin Yang This email address is being protected from spambots. You need JavaScript enabled to view it.

A: TESTN tests only zoned fields. To test a packed field, you could use Check/Check Right (CHECK/CHECKR) to test a character view of the field. Figure 2 shows a program I wrote that checks whether the program parameter contains a valid packed number. Call the program and pass it a packed field, the number of bytes in the packed field, and an “ok” field.

If the “ok” field returns a value of 1, the field contains valid packed data. You can easily modify this little program and include it as either a subroutine or a subprocedure in your programs.

— Barbara Morris

IBM Toronto Lab RPG Compiler Development

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

* To compile: *

* *

* CRTBNDRPG PGM(xxx/BM000R1) SRCFILE(xxx/QRPGLESRC) + *

* SRCMBR(BM000R1) *

* *

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

d valBegin c X'+

d 00010203040506070809+

d 10111213141516171819+

d 20212223242526272829+

d 30313233343536373839+

d 40414243444546474849+

d 50515253545556575859+

d 60616263646566676869+

d 70717273747576777879+

d 80818283848586878889+

d 90919293949596979899'

d valLast c x'+

d 0A0B0C0D0E0F+

d 1A1B1C1D1E1F+

d 2A2B2C2D2E2F+

d 3A3B3C3D3E3F+

d 4A4B4C4D4E4F+

d 5A5B5C5D5E5F+

d 6A6B6C6D6E6F+

d 7A7B7C7D7E7F+

d 8A8B8C8D8E8F+

d 9A9B9C9D9E9F'

d lastByte s 1a

c *ENTRY PLIST

c PARM charView 16

c PARM len 5 0

c PARM ok 1

* Check the last byte for digit (0-9) + sign (A-F)

C 1 SUBST charView:len lastByte

c valBegin CHECK lastByte 11=FD

* Check the first n-1 bytes for digits (0-9) in both nibbles

c EVAL len = len - 1

c valLast CHECKR charView:len 10=FD

*

c EVAL ok = NOT (*IN10 OR *IN11)

c IF ok = '0'

c 'invalid' DSPLY

c ELSE

c 'ok' DSPLY

c ENDIF

*

c RETURN

Figure 2: This program tests for numeric values in packed variables.

Separate Test and Production Environments

We often have separate test and production environments with separate copies of application database files. A problem I encounter when running a test or production program against the test database is that test results accidentally go to a production printer, thus confusing users, or that a test run in the test system accidentally triggers an EDI communication. The first problem is caused by the hardcoding of production OUTQs in CL programs, a simple way of getting output to an OUTQ other than the job’s default OUTQ. I added permanent code to the CL programs so the program uses production facilities (such as printers or EDI) if run in production but bypasses these facilities automatically if run in test. The code I added is shown in Figure 3.

In my example, “filename” is the name of a file found in either your test or your production database library. You find the name and type of that library to test whether you are using a test or production library. For this technique to work, you must ensure that all your database libraries are correctly classified as either TEST or PROD. This library type is easy to set:

CHGLIB LIB(library) TYPE(*TEST) or TYPE(*PROD)

Note that IBM has introduced a bit of inconsistency. With Change Library (CHGLIB), you must prefix TEST and PROD with an asterisk, but Retrieve Library Description (RTVLIBD) returns the library type without an asterisk.

— Richard Leitch This email address is being protected from spambots. You need JavaScript enabled to view it.

DCL VAR(&XCLIB) TYPE(*CHAR) LEN(10)

DCL VAR(&XCTYPE) TYPE(*CHAR) LEN(10)
:

:

RTVOBJD OBJ(filename) OBJTYPE(*FILE) +

RTNLIB(&XCLIB)
RTVLIBD LIB(&XCLIB) TYPE(&XCTYPE)
IF COND(&XCTYPE *EQ PROD) THEN(DO)
OVRPRTF FILE(printfile) OUTQ(production)
ENDDO
ELSE CMD(DO) /* You are in test */
OVRPRTF FILE(printfile) HOLD(*YES)

ENDDO

Figure 3: Add this code to your applications to ensure that your programs run in the correct environment.

Who Hosts That Address?

Looking for a way to determine, via a program, which TCP/IP host name is assigned to which TCP/IP address? File QATOCHOST in library QUSRSYS contains host table entries added using option 10 from the Configure TCP/IP (CFGTCP) menu. QATOCHOST contains IP addresses, host names, and descriptions. You can create a query or RPG program to generate a report of this information, which would be an improvement over the OS/400 TCP/IP Host Table Entries Information report, which you create via F6 from the Work with TCP/IP Host Table Entries panel. You can also use the Client Access file transfer function to download this information into the HOSTS file on your PC.

— Tim Cortez Worley Warehousing, Inc. This email address is being protected from spambots. You need JavaScript enabled to view it.

Editor’s Note: To the best of our knowledge, this is not a supported interface. Be aware that IBM may rename this file or store this information in another object in a future release of OS/400.

Using SQL to Merge Files

In years past, the RPG cycle and MR indicator allowed RPG programmers to merge the contents of files based on common keys. This technique was commonly known as matching records processing. Lately, however, the RPG cycle (and matching records processing in particular) has fallen out of favor, but the need to merge the contents of files still exists.

For those who have SQL on their AS/400s, there is an alternative to matching records processing. The trick is to use a union to merge data via a left join combined with an exception join. The left join selects all records from the primary file; the exception join picks up unmatched records from the secondary file. Using ORDER BY on the last union presents merged records in order.

You enter the SQL statement as shown in Figure 4. I have used this technique with IBM-supplied output files to match related information. For example, you can merge the output of the Display Object Description (DSPOBJD) command with corresponding Display File Description (DSPFD) *MBR information and use the merged information to generate reports via SQL (see Figure 5).

After you run these two commands, you can run the SQL statement shown in Figure 6 to merge the object and member creation information generated by the commands. The output of the SQL statement is a list of objects and their corresponding source members. You can run this statement interactively or run it within an SQL program. To handle null values returned for unmatched records when this statement is embedded in an SQL program, you must define a null indicator area or surround the field names with an

IFNULL function. For character fields, use IFNULL(FldNam, ‘ ‘); for numeric fields, use IFNULL(FldNam, 0).

— David Morris This email address is being protected from spambots. You need JavaScript enabled to view it.

SELECT Table1.Column1, Table2.Column2... From Table1
Left Join Table2 On Table1.Column1 = Table2.Column1
UNION ALL
SELECT Table1.Column1, ifnull(Table2.Column2, ' ')... From Table2
Exception Join Table1 On Table1.Column1 = Table2.Column1
Order By Table1.Column1, Table2.Column2
Figure 4: These SQL statements perform the matching record function.

DSPOBJD OBJ(OBJLIB/*ALL) OBJTYPE(*ALL) OUTPUT(*OUTFILE) OUTFILE(QTEMP/OBJ)
DSPFD FILE(SRCLIB/Q*) TYPE(*MBR) OUTPUT(*OUTFILE) OUTFILE(QTEMP/MBR)

Figure 5: This command loads a list of all objects in a given location to an *OUTFILE.

SELECT odlbnm, odobnm, mblib, mbfile, mbname, ... * From obj Left Join mbr On odsrcl = mblib And odsrcf =
mbfile And odsrcm = mbname Where Substr(odobnm,1,1) ¨= 'Q'
UNION ALL Select odlbnm, odobnm, mblib, mbfile, mbname ... From mbr Exception Join obj On mblib = odsrcl
And mbfile = odsrcf And mbname = odsrcm Where mbname ¨= ' ' Order By odlbnm, odobnm, mblib, mbfile,
mbname

Figure 6: These SQL statements merge the object and member creation information generated by the previous commands.

TESTN Negative

If you use the test numeric (TESTN) operation in your RPG programs, you should be aware of how negative numbers are tested. To review, TESTN determines whether a character field contains all numeric data, numeric data with leading spaces, all spaces, or none of the above. When stored in a character field, negative numbers encode the sign into the rightmost character.

Uppercase letters J through R represent -1 through -9, respectively (hexadecimals D1 through D9), and the right brace (}) represents zero in a negative number (hexadecimal D0). Consequently, a field defined as 5a with a value of 1234} becomes -12340 when moved to a numeric field defined as 5.0. This means that your character field turns on the HIGH indicator in a TESTN operation, indicating all numeric data. Furthermore, if the rightmost character is an uppercase letter from A through I (hexadecimals C1 through C9) or the left brace ({) (hexadecimal C0) and all other characters are numeric, this field also tests as all numeric data. Try it yourself. Uppercase letters A through I translate to positive 1 through 9, respectively, and the left brace ({) becomes zero when moved to a numeric field.

Suppose your system receives an electronic data interchange (EDI) purchase order from your trading partner and one of the fields received is an order quantity sent to you in a mutually agreed upon character field. In addition, suppose your batch RPG program always edits this field for actual numeric data before moving the character field to a numeric field, subsequently creating a sales order. Would receiving a value of 1000A cause a problem? A TESTN on this field passes, and congratulations! You’ve just ordered 10,000 widgets for your trading partner when they wanted only 1,000. Imagine the surprise if a shipment actually hits their receiving dock.

Fortunately, the workaround for this particular situation is simple, as shown in the code fragment in Figure 7. Just move your character field left into a bigger character field before the TESTN statement. Make certain that the rightmost character of the bigger field is a number from 0 through 9, and TESTN will work as you expect. Another solution would be to use the CHECK operation to scan explicitly for just the numbers 0 through 9.

— Chris Ringer This email address is being protected from spambots. You need JavaScript enabled to view it.

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

* To compile: *

* *

* CRTBNDRPG PGM(xxx/CR000R1) SRCFILE(xxx/QRPGLESRC) + *

* SRCMBR(CR000R1) *

* *

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

D CharQty s 5a Inz('1000A')

D IntQty s 5s 0

D Char30 s 30a

D Wk0to9 c Const('0123456789')

* Using TESTN HiLoEq

C move *ZEROS Char30

C movel CharQty Char30

C testn Char30 50

C If (*IN50 = *On)

C move CharQty IntQty

C else

* ..not numeric

C endif

* Using CHECK

C Wk0to9 Check CharQty 50

C If (*IN50 = *Off)

C move CharQty IntQty

C else

* ..not numeric

C endif

Figure 7: This code fragment tests for numeric values in negative numbers.

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: