File names in JCL

As a result of reading Lyn Elkins’ posts about how she struggled with the quotation marks required to specify a file name as a parameter in a JCL PARM string, I thought I would write a little summary. I personally prefer to use DD cards for my file names whenever possible as these avoid the need for quotation marks and leave your eye less likely to be squinting by the time you are done. I will show the fully qualified example right at the end for anyone who really wants it though. I am using QLOAD as an example program here, but any application that simply does an fopen() can make use of the same syntax. For example, when supplying a script in a file using MQSCX, providing an input file to load onto a queue in QLOAD, or some string data to become message data in the Q program. Any parameter that expects a file name can also instead take a string of the format “DD:card-name” (note that you MUST use capital letter D’s here). All of these use the same syntax as illustrated here.

//QLOAD    JOB
//*********************************************************************
//* QLOAD Load messages onto Q1
//*********************************************************************
//LOADTOQ  EXEC PGM=QLOAD,
//         PARM=('-m MQG1 -o Q1 -f DD:INFILE1')
//STEPLIB  DD DSN=GEMUSER.USER.LOAD,DISP=SHR                         
//         DD DSN=IBM.MQ.SCSQAUTH,DISP=SHR                           
//         DD DSN=IBM.MQ.SCSQANLE,DISP=SHR                           
//SYSPRINT DD SYSOUT=*  
//SYSOUT   DD SYSOUT=*      
//INFILE1  DD DSN=GEMUSER.DATA.MSGFILES(EXMPL1),DISP=SHR
//INFILE2  DD DSN=GEMUSER.DATA.OUTPUTQ1,DISP=SHR 
//INFILE3  DD PATH='/u/gemuser/Q1.qld',PATHOPTS=(ORDONLY)          
//MQGEML   DD DSN=GEMUSER.MQGEM.LIC,DISP=SHR
//

Here you can see that the JCL PARM string does not need any extra quotes at all, just the string DD:INFILE1 where INFILE1 is the name of a DD card in the JCL job. The DD card can then specify a fully qualified PDS member, MVS file, or HFS file as the three examples show.

To do the same job as shown in these three examples by providing the file name inline in the JCL PARM string, things start getting complicated by the fact that extra quotation makes are needed to escape the quotes since the whole JCL PARM string is surrounded by single quotes itself. This is what makes it so problematic, and why I always use DD cards instead.

If you take advantage of that the fact that MVS knows your TSO login and will pre-pend it to the MVS file name you supply, you can avoid quite a number of the quotation marks needed. The following two EXEC statements are equivalent when the TSO login is GEMUSER. The way you tell MVS not to pre-pend your TSO login is to surround the name you supply with single quotes, which turn into doubled up single quotes when used inside a JCL PARM string! The whole thing also needs to be enclosed in double quotes because of the slashes which are considered a delimiter to separate a JCL PARM string into run-time options and parameters to pass to the program.

//LOADTOQ  EXEC PGM=QLOAD,
//         PARM=('-m MQG1 -o Q1 -f"//DATA.MSGFILES(EXMPL1)"')
//LOADTOQ  EXEC PGM=QLOAD,
//         PARM=('-m MQG1 -o Q1 -f"//''GEMUSER.DATA.MSGFILES(EXMPL1)''"')

The two slashes shown in both the above example JCL PARM strings are how you tell fopen() that you are referencing an MVS file (to distinguish it from an HFS file). Here is an example EXEC statement using an HFS file instead. Again, this string needs to be surrounded by double quotes because of the slashes. The second example has no slashes, and will end up in your current directory. In fact any string that does not start with DD: or a slash (or two) will be interpreted as an HFS file in your current directory, and is why you might end up with an HFS file called “dd:SUMMARY” if you forgot to use capital letter D’s.

//LOADTOQ  EXEC PGM=QLOAD,
//         PARM=('-m MQG1 -o Q1 -f"/u/gemuser/Q1.qld"')
//LOADTOQ  EXEC PGM=QLOAD,
//         PARM=('-m MQG1 -o Q1 -fQ1.qld')

Well, I hope that helps, and also probably convinces you that DD cards are the way to go.

I didn’t invent this stuff, I’ve just spent a lot of time using it. Here is some reference material that helped me get to grips with it. Perhaps it can help you too.

On a separate note, if you ever have a long JCL PARM string, don’t struggle with line continuations, move over to using PARMDD – see JCL with long PARM strings

Loading files to multiple queues

If you have unloaded MQ message data in a file that you need to load onto a queue, you can use QLOAD with an invocation something like this:

qload -m MQG1 -o Q1 -f msgtext.qld

If you have files containing message data that wasn’t written by QLOAD, you can still load it up again with QLOAD. See QLOAD: Using delimited files. The mechanisms in this blog post can also be combined with those types of message data files.

Since QLOAD V8.0.2 you have also been able to load a file up onto multiple queues like this:

qload -m MQG1 -o Q1 -o Q2 -o Q3 -o Q4 -f msgtext.qld

In other words you can repeat the -o parameter as often as required. This operation will make use of distribution lists in IBM MQ unless you force the use of individual MQOPENs with the -OI flag. When running QLOAD on z/OS, this latter mechanism is always used.

The queue names specified on the -o parameters can be fully qualified destinations, for example MQG2/Q1, that is Q1 on queue manager MQG2.

If you have quite a lot of queues and you don’t want to specify lots of -o parameters, you can instead put the list of queue names into a destination file and tell QLOAD to use that, with an invocation something like this:

qload -m MQG1 -o file:mydestinations.dst -f msgtext.qld

Your destination file might look something like this, illustrating comment lines and the fact that you can also include other destination files:

* This file contains queue destinations used by QLOAD
MQG1/Q1
MQG2/Q1
MQG3/Q1

* You can even load other files
file:moredestinations.dst

mydestinations.dst

If you’re running QLOAD on z/OS, you could make use of an inline DD card to keep all the listed queue names in a single piece of JCL, or you might reference another file if you are using the same list of queue names over and over.

//QLOAD    JOB
//*********************************************************************
//* QLOAD Load to many queues
//*********************************************************************
//PUTMANY  EXEC PGM=QLOAD,
//         PARM=('-m MQG1 -o "file:DD:QLIST1" -f DD:MSGTEXT')
//STEPLIB  DD DSN=GEMUSER.USER.LOAD,DISP=SHR                         
//         DD DSN=IBM.MQ.SCSQAUTH,DISP=SHR                           
//         DD DSN=IBM.MQ.SCSQANLE,DISP=SHR                           
//SYSPRINT DD SYSOUT=*  
//SYSOUT   DD SYSOUT=*      
//MSGTEXT  DD DSN=GEMUSER.MSGFILES(EXMPL1),DISP=SHR
//MQGEML   DD DSN=GEMUSER.MQGEM.LIC,DISP=SHR
//QLIST1   DD *
Q1
Q2
Q3
Q4
/*
//

This is not a new feature of QLOAD – it has been there since January 2016, but I was prompted to write about it because of a question from someone who didn’t know about the destination files.


Read more about the QLOAD program, and download a copy, from the QLOAD Download Page. If you don’t have a licence and would like to try out QLOAD then send an email to support@mqgem.com and a 1-month trial licence will be sent to you.

Is there a way to clear an MQ queue of all messages?

We were recently asked how to clear a queue of all messages within one of our tools.

In this post we cover how to do this using MQGem tools as several of them offer this capability. Open up the twisty for each tool to read how to do this.

Using MO71

There are two options for clearing a queue of all messages when using MO71. One directly interacts with the messages in a Message List dialog, and the other uses the Clear Queue command via the command server. The latter can fail if someone else has the queue open.

MO71: Using the Message List dialog

In MO71 you can browse a list of messages on a queue, then in the context menu of that dialog choose Message Selection → Apply to all Messages. Then press the Delete All button, or select Delete All from the right-mouse button context menu and all the messages will be deleted.

Delete all messages using MO71

Take care when deleting messages from a production queue manager. Consider that it might be safer to Move the message(s) to a separate holding queue, just in case the message proves to be important after all. MO71 makes it simple to Move messages too. Just fill in the holding queue name, and then press the Move All, rather than Delete All, button.

MO71: Using the Clear Queue command

From a Queue List dialog in MO71, you can choose to clear a queue from the context menu. As a destructive command, this will show a confirmation dialog before it goes ahead.

Delete all messages using the Clear command in MO71

Remember that this command can fail if the queue is open by another application at the time.

Using the Q program

You can use the Q program to quickly destructively get off all the messages on a queue, to ensure it is empty before you begin using it for something else. This can work even when the queue is in use (unless it is exclusively in use of course) and the CLEAR QLOCAL command can’t be used.

Here is an example which destructively gets (-I) from Q1 and does not print the messages to the screen (-q), aka ‘quiet’ mode:-

q -m MQG1 -I Q1 -q

Take care when deleting messages from a production queue manager. Consider that it might be safer to Move the messages to a separate holding queue, just in case they prove to be important after all. This is simple to achieve using a command like the following:

q -m MQG1 -I Q1 -o HOLDING.Q
Using QLOAD

You can use QLOAD to quickly destructively get off all the messages on a queue, to ensure it is empty before you begin using it for something else. This can work even when the queue is in use (unless it is exclusively in use of course) and the CLEAR QLOCAL command can’t be used.

Here is an example which destructively gets (-I) from Q1 and discards them (-f null), aka sends them to the null file destination:-

qload -m MQG1 -I Q1 -f null

Take care when deleting messages from a production queue manager. We would recommend using QLOAD to actually move the messages to an output file, in case you change your mind about deleting them!

qload -m MQG1 -I Q1 -f c:\temp\Q1deletedmsgs.qld 
Using MQEdit

In MQEdit you can browse a list of messages on a queue, then in the context menu of that dialog choose Message Operations → Apply to all Messages. Then press the Delete All button, or select Delete All from the right-mouse button context menu and all the messages will be deleted.

Delete all messages using MQEdit

Take care when deleting messages from a production queue manager. Consider that it might be safer to Move the message(s) to a separate holding queue, just in case the message proves to be important after all. MQEdit makes it simple to Move messages too. Just fill in the holding queue name, and then press the Move All, rather than Delete All, button, or simply Drag and Drop the messages onto the new queue.

Using MQSCX

You can of course issue the MQSC CLEAR QLOCAL(q-name) command from MQSCX. However, it can go one better than this. The CLEAR QLOCAL command is problematic because it can fail when someone else has the queue open, even if it is not open in a way that stops you getting messages. Instead you can issue the following command in MQSCX:-

=clear qlocal(Q1)

then MQSCX will first attempt the CLEAR QLOCAL command and if that fails with "object in use" then it will switch to getting the messages off the queue instead. You can read more about this in MQSCX: Clearly a better way.


If you don't have any of these tools, but would like to try any or all of them out, please contact support@mqgem.com and a 1-month trial licence will be sent to you with no obligation to buy. You can download the tools from our website.

Loading Messages with the correct context

One of the benefits of using QLOAD to unload and then reload your messages is that the full MQMD is also saved and restored, so you don’t lose the context fields of your messages. They still show the original putting application and user ID just as before they were unloaded, and the put date and time fields stay the same as well.

What are the context fields?

In case you don’t remember, here’s a quick summary of the MQMD Context fields. There are two sets of context fields, the Identity Context and the Origin Context. It is possible to manipulate just the Identity Context fields or all the fields as we’ll see in a moment.

Identity Context Fields Origin Context Fields
UserIdentifier PutApplType
AccountingToken PutApplName
ApplIdentityData PutDate
  PutTime
  ApplOriginData

If you want a quick refresher on how authorisations work with these fields, check out this Morag’s Quirks blog post.

Manipulating Context fields

By default QLOAD will do the puts when you load messages onto a queue using “Set All Context” which means all the fields that are saved in the unloaded file are put back in the newly loaded up messages.

If you prefer to upload the messages and record new context fields to show that they are from you, then you can tell QLOAD you use a different context option. The following command will set all the context fields to identify QLOAD as the application that put the messages, and the user that is running QLOAD as the User Identifier. This is known as “Default Context” and is indicated using the -Cd flag (Context – default).

qload -m MQG1 -o Q1 -f Q1-messages.qld -Cd

If you want to just keep the identity context fields as they were in the unload file, and have the origin context fields reflect what’s happening now you can use the “Set Identity Context” option, -CI flag (Context – Identity).

qload -m MQG1 -o Q1 -f Q1-messages.qld -CI

Another option that can be very useful is to have all these MQMD fields be exactly as they were when unloaded with the exception of the Put Date and Time fields. This isn’t an MQ option, it’s just something that QLOAD offers you. It uses “Set All Context” and grabs a new timestamp for your Put Date and Time fields just before it puts the message to the queue. You can do this by using the -Ct flag (Context – time).

qload -m MQG1 -o Q1 -f Q1-messages.qld -Ct

This particular option can be very useful if you save off message data to replay in testing scenarios. Everything else stays the same, but the messages reflect the fact that they have been put right now.

There are a number of other context options for when you are moving messages not from a file, but from a queue. These can be found in the QLOAD User Guide, or by reading the QLOAD program help.

qload -C?

QLOAD can be downloaded from our webite. If you don’t have a licence and would like to try out QLOAD then send an email to support@mqgem.com and a 1-month trial licence will be sent to you.

Finding the reason why a message was sent to the Dead Letter Queue (DLQ) in IBM MQ

IBM Support recently released a Support Doc which was titled:-

Summary

Finding the reason why a message was sent to the Dead Letter Queue (DLQ) in IBM MQ

The document described several options, which often required you to look at the message in hex and, when required, byte swap the value to find the reason code. In this post we cover how to do this using MQGem tools as several of them offer this capability, and our tools format out the Dead Letter Header so you don’t need to do any manual byte swapping. Open up the twisty for each tool to read how to do this.

Using MO71

In MO71 you can browse the messages on the Dead Letter queue using a Message List. If you choose to show the “Message Summary” column on your list dialog (see Configuring List Dialogs in MO71 for how to change the columns in a list dialog), you will immediately be able to see the reason code in the Dead-Letter header, as that is one of the useful things that Message Summary displays look for.

A message List dialog will summarise the Dead Letter header of a message for you

Alternatively you can double click on a message to look at the full details of an individual message, and you will see the full Dead-Letter header (MQDLH) is formatted out for you to see.

The full message display shows all of the Dead Letter Header formatted out

Using the Q program

To view your messages on the Dead Letter queue, and have them formatted out, you need to use the -df option which also has three levels of detail. For full detail use -df3. Here’s an example command:-

q -m MQG1 -i MQG1.DEAD.LETTER.QUEUE -df3

Which will format the Dead Letter header like this making it really easy to understand the reason why the message was placed on the DLQ.

[  181 bytes] Message Content
[  181 bytes] Dead Letter Queue Header (MQDLH)
StrucId      :'DLH '
Version      :1
Reason       :2085 (Unknown object name)
Dest. Queue  :'TARGET.QUEUE                                    '
Dest. QMgr   :'MQG1                                            '
MQEncoding   :0x'222' (Reversed)
CCSID        :437 (IBM PC)
Format       :'MQSTR   ' (String)
PutApplType  :11 (Windows NT)
PutApplName  :':\mqm9250\bin64\amqrmppa.exe'
Put Date     :'20220411'
Put Time     :'05021009'
Some text
Using MQEdit

When you look at the messages on a queue using MQEdit, the message list will show you a summary of the message in the “Message” column, which for Dead Letter header messages will show you the reason from the header. This makes it very easy to see the reasons why messages are on your Dead Letter queue.

Selecting a message from the list will display it in the pane below with the Dead Letter header formatted out also showing you the reason why the message ended up on the DLQ.

MQEdit shows a summary of the Dead Letter header in the message list, and the fully formatted message in the lower panel

Using QLOAD (honourable mention)

QLOAD isn’t a message formatting tool, so it will not help you to view the reason code in the Dead Letter header of a message. However, it does get an honourable mention in this list because it can help you to move, or unload messages from your Dead Letter queue that have a specific reason code in the Dead Letter header. This can be very helpful if you want to siphon off some specific errors to handle in a different way.

Use a command like this to copy (-i is browse) all the DLQ messages for MQRC_UNKNOWN_OBJECT_NAME (2085) to a file.

qload -m MQG1 -i MQG1.DEAD.LETTER.QUEUE -Gr:2085 -fUnknownObjs.qld

When you’re using this feature, QLOAD will report the message selection that you have active:-

Message selection active:
  Messages with DLQ Reason 2085 Unknown object name

Read    - Files:   0  Messages:     3  Bytes:      5616
Written - Files:   1  Messages:     1  Bytes:       181

If you don’t have any of these tools, but would like to try any or all of them out, please contact support@mqgem.com and a 1-month trial licence will be sent to you with no obligation to buy. You can download the tools from our website.

QLOAD Summary display

When you have a few messages on a queue, and you’re not sure why, one of the questions you may ask yourself is how old these messages are.

The IBM MQ DISPLAY QSTATUS command can tell you how old the oldest message on the queue is when you look at the MSGAGE attribute, but that doesn’t tell you about the other not quite so old messages. You can also see the depth of the queue using MQ administrative commands, but you don’t get any information about the size of the messages.

The QLOAD Summary display can give you a snapshot of the various messages on your queue. Invoke QLOAD with a command like the following:-

qload -m MQG1 -i<queue-name> -ds

to see a report something like this:-

Message Ages
============

< 2  secs < 10 secs < 1   min < 1  hour < 1   day < 1  week
--------- --------- --------- --------- --------- ---------
        0         0         0         0         0         2

< 2 weeks < 4 weeks < 3 month < 6 month < 1  year > 1  year
--------- --------- --------- --------- --------- ---------
        2         2        13       110         0         0

Youngest Message : 4 Days 2 Hrs 29 Mins 28 Secs

Oldest   Message : 19 Weeks 3 Days 3 Hrs 26 Mins 7 Secs

Message Sizes
=============

< 100b <  1Kb <  4Kb <100Kb <  1Mb < 10Mb < 50Mb > 50Mb
------ ------ ------ ------ ------ ------ ------ ------
     1    128      0      0      0      0      0      0

Smallest Message : 4 bytes

Biggest  Message : 368 bytes

This is not a new feature of QLOAD – it had been there a very long time, and was enhanced in the V9.1.1 which was released in August 2019, but I was prompted to write about it because of a question from someone who didn’t know about this report.


Read more about the QLOAD program, and download a copy, from the QLOAD Download Page. If you don’t have a licence and would like to try out QLOAD then send an email to support@mqgem.com and a 1-month trial licence will be sent to you.

Is there a way to delete a single message from an MQ queue?

IBM Support recently released a Support Doc which posed the question:-

Question

Is there a way to delete a single message from an MQ queue (arbitrary position in the queue)?

The document described a couple of options. In this post we cover how to do this using MQGem tools as several of them offer this capability. Open up the twisty for each tool to read how to do this.

Using MO71

In MO71 you can browse a list of messages on a queue, then from that list, select an individual message (or multiple messages if you need to). Then press the Delete button, or select Delete from the right-mouse button context menu and the selected message(s) will be deleted.

MO71 uses the MQ facility, get by message token, so only the exact message(s) that you select from the list will be deleted. While the position of the message on the queue is shown, this is not used for deletion and neither is Message Id, since there is no guarantee that this will be unique either. Each message on a queue is guaranteed to have a unique Message Token.

Alternatively, you can double click on a message from the list, to view the whole message individually. Then from that display, having checked all the details, and made sure it is the message you want to delete, you can press the Delete button, or select Delete from the context menu.

Take care when deleting messages from a production queue manager. Consider that it might be safer to Move the message(s) to a separate holding queue, just in case the message proves to be important after all. MO71 makes it simple to Move messages too. Just fill in the holding queue name, and then press the Move, rather than Delete, button.

Using the Q program

To delete a single message from an MQ queue using the Q program, you should first discover the message ID of the message you wish to delete, to ensure you are addressing the correct message that you intend to delete. Do this by displaying the messages on the queue like this:-

q -m MQG1 -i Q1 -dd

This will browse (-i) the messages on the queue and display the MQMD after the MQGET (-dd) allowing you to see the Message ID of each message on the queue. You will see output like this for each message:-

==============================================================
----- MQMD after MQGET -----
[  324 bytes] Message Descriptor (MQMD)
Report       :00000000
Message Type :8 (Datagram)
Format       :'MQSTR   ' (String)
Priority     :0 (Lowest)
Persistence  :0 (Not Persistent)
Message Id   :414D51204D514731202020202020202099FA4A6020B74B02
              A M Q   M Q G 1                 . ú J `   · K .
ReplyToQ     :'                                                '
ReplyToQMgr  :'MQG1                                            '

Now you can copy that message ID and use it on another invocation of the Q program to delete that specific message from the queue.

q -m MQG1 -IQ1 -gxm:414D51204D514731202020202020202099FA4A6020B74B02

Bear in mind that message IDs are likely to be unique, but this is not guaranteed. It would be safer to move the messages to a separate queue, before deletion. This is simple to achieve using a command like the following:

q -m MQG1 -IQ1 -o HOLDING.Q 
-gxm:414D51204D514731202020202020202099FA4A6020B74B02
Using QLOAD

If you have already browsed the queue contents and output them to a file, you can find the message Id of the specific message you are attempting to address by looking for the Message Descriptor attribute “MSI”. Here is a snippet from a QLOAD file to show an example.

A FMT MQSTR
A PRI 0
A PER 0
A MSI 414D51204D514731202020202020202099FA4A6020B74B02
A COI 000000000000000000000000000000000000000000000000

Now you can copy that message ID and use it on another invocation of the QLOAD program to delete that specific message from the queue. We would recommend using QLOAD to actually move that message to an output file, in case you change your mind about deleting it!

qload -m MQG1 -IQ1 -f c:\temp\deletedmsg.qld 
-gxm414D51204D514731202020202020202099FA4A6020B74B02

Alternatively, you can use the very flexible search and filtering capabilities of QLOAD to narrow down your search of messages on the queue until you find the one you wish to delete, and then offload it to a file, or delete it entirely.

For example, this invocation removes all messages on a queue that are older than one week, and moves them instead to the named file:-

qload -m MQG1 -I Q1 -T7:0:0 -f c:\temp\oldmsgs.qld

Another example, here we remove messages larger than 1MB from a queue:-

qload -m MQG1 -I Q1 -z 1M -f c:\temp\bigmsgs.qld

A third example, here we remove message containing the string “Acme Limited”:-

qload -m MQG1 -I Q1 -s "Acme Limited" -f c:\temp\acmemsgs.qld
Using MQEdit

In MQEdit you can browse a list of messages on a queue, then from that list, select an individual message (or multiple messages if you need to). Then press the Delete button, or select Delete from the right-mouse button context menu.

MQEdit uses the MQ facility, get by message token, so only the exact message that you select from the list will be deleted. While the position of the message on the queue is shown, this is not used for deletion and neither is Message Id, since there is no guarantee that this will be unique either. Each message on a queue is guaranteed to have a unique Message Token.

Alternatively, you can double click on a message from the list, to view the whole message individually in the pane below, and then from that pane, having checked all the details, and made sure it is the message you want to delete, you can select “Delete Message” from the context menu.

Particularly for production queue managers, we would always suggest that it is safer to move message(s) to a holding queue rather than deleting them immediately. In MQEdit it is very simple to move a message between queues, all you need do is drag and drop the required message(s) from one queue to another. You can even copy and move messages between queue managers this way.


If you don’t have any of these tools, but would like to try any or all of them out, please contact support@mqgem.com and a 1-month trial licence will be sent to you with no obligation to buy. You can download the tools from our website.

Text Files in Preview Pane

If you’re anything like me, you have a number of text files on your Windows machine that do not use the .txt file extension.

For all of these I have associated Notepad as the application to be used by default when I double click on these file types from the Windows File Explorer. I’m probably a 70:30 command line vs File Explorer user, but it is from time to time handy to be able to double click too.

What I’d never managed to figure out though (until today) was how to get the preview pane in Windows File Explorer to display these text formats with different file extensions. Now that I have found out how to do it, I thought I would share it with all of you too.

Windows File Association Dialog

Windows File Association Dialog

Firstly, it’s important to have the file association in place first, specifically the “Always use this app to open … files” checkbox. This seems to be what adds the file extension into the list you are about to manipulate. So take a moment to make sure all the extensions you want to preview have a default application set.

Now open the registry editor and navigate to Computer > HKEY_CLASSES_ROOT. In here you will see a list of all the file extensions your machine knows about. Locate your file extension that you want to preview (remember you can type into the entry field just below the menu bar). Select the file extension, in this example I am fixing up the .mqx extension; and on the right hand pane right-click and select New > String Value. Give the new key the name “PerceivedType” and then modify it to give it the data value of “text”.

Adding a new String Value in Windows Registry

Adding a new String Value in Windows Registry

Giving new registry key a value of text

Giving new registry key a value of text

Now go back to your File Explorer and you should be able to see your .mqx file in the preview pane.

View .mqx file in Preview Pane

View .mqx file in Windows File Explorer Preview Pane


Many thanks to Scott Williams who wrote about this in a blog post in 2013 which I finally stumbled across in 2020 and it made my day!

JCL with long PARM strings

Prompted by Colin Paice’s recent blog post on bringing your JCL out of the 1960s, I thought I would write this post about a new feature of JCL I recently discovered.

I am quite comfortable creating/editing JCL, but one thing I do hate with a passion is long PARM strings. I can never remember quite which column the continuation line is supposed to start on, and it just makes your parameters hard to read too. You may have noticed a number of features in our recently provided products on z/OS which help to keep PARM strings short.

When testing our recently released QLOAD on z/OS, where there simply are times when you need long PARM strings, I came across a recently added JCL feature called PARMDD. I believe it was added in z/OS 2.1.

Instead of coding the PARM parameter on an EXEC statement inline, this instead allows you to point it to a DD card where you have then have as many lines of parameters as you need. These various lines are stripped of their trailing white space, concatenated together and then passed to your program. You can have this DD card point to a file, but I like to have the parameters inline in the same JCL file.

Here’s an example of one such long parameter when using the QLOAD delimited file feature.

//QLOAD    JOB
//*********************************************************************
//* QLOAD Load Delimited File
//*********************************************************************
//DELIMQL  EXEC PGM=QLOAD,PARMDD=PARMS
//PARMS    DD   *
-m MQG1 -o Q1 -Cd -f"DD:DELIM" -nF -n"is:<msg>" -n"ie:</msg>"
 -n"ip:<usr>" -n"iq:</usr>"
/*
//STEPLIB  DD DSN=GEMUSER.USER.LOAD,DISP=SHR                         
//         DD DSN=IBM.MQ.SCSQAUTH,DISP=SHR                           
//         DD DSN=IBM.MQ.SCSQANLE,DISP=SHR                           
//SYSPRINT DD SYSOUT=*  
//SYSOUT   DD SYSOUT=*      
//DELIM    DD DSN=GEMUSER.MSGFILES(EXMPL1),DISP=SHR
//MQGEML   DD DSN=GEMUSER.MQGEM.LIC,DISP=SHR
//

Now isn’t that so much easier to use and to read, than your standard continuation PARM parameter?


If you want to give this JCL feature a try, I think you just need to be on at least z/OS 2.1, and I’ve provided the link to the JCL Reference above.

You can download QLOAD for z/OS from the QLOAD Download Page. If you’d like to try out QLOAD on z/OS, please email support@mqgem.com and a 1-month trial licence will be sent to you.

QLOAD on z/OS

MQGem Software is pleased to announce that QLOAD, our queue load/unload tool for IBM MQ, is now available natively on z/OS.

Back when QLOAD was a SupportPac, it was available on the z/OS platform, and we are pleased to be able to once again provide it on z/OS.

QLOAD has evolved somewhat from the days when it was a SupportPac, and there have been many features added since then. These features are now also available natively on z/OS. Some of the highlights of those additional features include:

  • Using Delimited Files
    Originally QLOAD only read in files in its native format, but this feature allows files of any format to be used to load messages onto queues, one message per line, or with delimiter marking the start and end of each message. Read more here.
  • Required Rate
    This feature of QLOAD allowed you to test whether your system can handle a particular rate of messages, or even discover what rate of message your system can handle. Read more here.
  • Generic Unload/Load
    Perhaps you need to migrate a queue manager? This feature of QLOAD allows you to unload messages off all your queues, to files, with a single command. Read more here.
  • Using SQL92 selectors in QLOAD
    QLOAD has always had a number of different ways to filter the messages when you are unloading them. In MQGem’s QLOAD, you can also make use of the SQL92 selector string to filter your messages. Read more here.
  • And many more…
    If you have been a user of QLOAD on z/OS at the SupportPac feature level, I strongly recommend you download the user guide and go to the very back of the guide and page through the sections detailing “what’s new” in each release, to get a full picture of all the features that have been added to QLOAD since MQGem released it.

To enable QLOAD to run on z/OS you require a z/OS specific licence. A distributed platform QLOAD licence will not enable QLOAD on z/OS to run.


You can download QLOAD for z/OS from the QLOAD Download Page. If you’d like to try out QLOAD on z/OS, please email support@mqgem.com and a 1-month trial licence will be sent to you.