Mainframe Tips, Tricks And Tutorials
Mainframe tips
Monday, July 27, 2026
Building an MQ Queue Depth Alert Program in COBOL
𝗣𝗿𝗲𝘃𝗲𝗻𝘁𝗶𝗻𝗴 𝗗𝗕𝟮 𝗧𝗮𝗯𝗹𝗲 𝗖𝗼𝗻𝘁𝗲𝗻𝘁𝗶𝗼𝗻 𝗕𝗲𝘁𝘄𝗲𝗲𝗻 𝗦𝗘𝗟𝗘𝗖𝗧 𝗚𝗿𝗼𝘂𝗽𝘀 𝗮𝗻𝗱 𝗨𝗽𝗱𝗮𝘁𝗲 𝗝𝗼𝗯𝘀 𝗶𝗻 𝗘𝗦𝗣
- Multiple
SELECT jobs can run concurrently.
- JOBX
runs exclusively.
- No
SELECT job can run while JOBX is running.
- No lengthy NOTWITH statements are required.
- Multiple SELECT Group jobs can run simultaneously because they all hold a SHARED enqueue on MY_TABLE.
- JOBX cannot start while any SELECT job is running because it requires EXCLUSIVE access.
- Likewise, no SELECT job can start while JOBX holds the exclusive enqueue.
- The solution is simple, scalable, and requires minimal maintenance as SELECT jobs are added or removed.
𝗦𝗰𝗮𝗻𝗻𝗶𝗻𝗴 𝗮 𝟰𝟬 𝗞𝗕 𝗗𝗮𝘁𝗮 𝗔𝗿𝗲𝗮 𝗳𝗼𝗿 𝗟𝗼𝘄𝗲𝗿𝗰𝗮𝘀𝗲 𝗖𝗵𝗮𝗿𝗮𝗰𝘁𝗲𝗿𝘀: 𝗔 𝟱𝟬-𝗠𝗜𝗣𝗦 𝗢𝗽𝘁𝗶𝗺𝗶𝘇𝗮𝘁𝗶𝗼𝗻 𝗦𝘁𝗼𝗿𝘆
Saturday, July 25, 2026
𝗢𝗽𝘁𝗶𝗺𝗶𝘇𝗶𝗻𝗴 𝗮 𝗠𝗶𝗰𝗿𝗼 𝗙𝗼𝗰𝘂𝘀 𝗖𝗢𝗕𝗢𝗟 𝗣𝗿𝗼𝗴𝗿𝗮𝗺: 𝗥𝗲𝗱𝘂𝗰𝗶𝗻𝗴 𝗥𝘂𝗻𝘁𝗶𝗺𝗲 𝗳𝗿𝗼𝗺 𝟲𝟬 𝘁𝗼 𝟭𝟱 𝗠𝗶𝗻𝘂𝘁𝗲𝘀
𝗔 𝗦𝗶𝗺𝗽𝗹𝗲 𝗧𝗲𝗰𝗵𝗻𝗶𝗾𝘂𝗲 𝘁𝗼 𝗘𝗻𝘀𝘂𝗿𝗲 𝗢𝗻𝗹𝘆 𝗢𝗻𝗲 𝗝𝗼𝗯 𝗥𝘂𝗻𝘀 𝗮𝘁 𝗮 𝗧𝗶𝗺𝗲 𝗶𝗻 𝗮 𝗚𝗿𝗼𝘂𝗽 𝗼𝗳 𝗣𝗮𝗿𝗮𝗹𝗹𝗲𝗹 𝗝𝗼𝗯𝘀
As a result:
- The
first job that acquires the dataset proceeds normally.
- Any
other job that also requests the same dataset with DISP=OLD must wait
until the dataset is released.
- Since the DD statement is present in the last step of each job, the dataset remains allocated until that step completes, effectively ensuring that only one job from the group runs at a time.
Monday, July 20, 2026
Why Binary Fields Never Cause an S0C7 Abend, but Zoned Decimal and Packed Decimal Can
Binary fields will NEVER cause S0C7 abend
This is demonstrated using the below COBOL code.
WORKING-STORAGE SECTION.
01 JUNK PIC X(04).
01 WS-BINARY REDEFINES JUNK PIC 9(08) COMP.
PROCEDURE DIVISION.
MOVE 'ABCD' TO JUNK.
DISPLAY 'WS-BINARY: ' JUNK WS-BINARY
ADD 1 TO WS-BINARY
DISPLAY 'WS-BINARY: ' JUNK WS-BINARY
MOVE '#$%=' TO JUNK.
DISPLAY 'WS-BINARY: ' JUNK WS-BINARY
ADD 1 TO WS-BINARY
DISPLAY 'WS-BINARY: ' JUNK WS-BINARY
WS-BINARY: 50766789
WS-BINARY: 69589118
WS-BINARY: 69589119
'ABCD' is indirectly moved to WS-BINARY. The hexadecimal equivalent of 'ABCD' is X’C1C2C3C4’. If you put this HEX decimal value in calculator, you will get 3,250,766,788. Since picture clause of WS-BINARY is 9(8), the last 8 digit 50,766,788 is displayed in the first DISPLAY statement.
When you add 1 to this value(3,250,766,788), it become 3,250,766,789 and second DISPLAY statement displays last 8 digits which is 50,766,789.
Case 2: Value "#$%="
'#$%=' is indirectly moved to WS-BINARY. The hexadecimal equivalent of '#$%=' is X’7B5B6C7E’. If you put this HEX decimal value in calculator, you will get 2,069,589,118. Since picture clause of WS-BINARY is 9(8), the last 8 digit 69,589,118 is displayed in the third DISPLAY statement.
When you add 1 to this value(2,069,589,118), it become 2,069,589,119 and fourth DISPLAY statement displays last 8 digits which is 69,589,119.
Typical zoned decimal declarations in COBOL are shown below:
01 WS-NUMBER1 PIC 9(5). -> Unsigned zoned decimal
01 WS-NUMBER1 PIC 9(5)V99. -> Unsigned zoned decimal
01 WS-NUMBER2 PIC S9(5)V99. -> Signed zoned decimal
Internal representation of Zoned Decimal in Memory
In a zoned decimal field:
- Each decimal digit occupies one byte.
- Each byte has 2 nibbles, and each nibble has 4 bits.
- The high-order 4 bits (zone portion) of each byte will always have b’1111’ (hex F) except the last byte.
- The low-order 4 bits (decimal portion) contain the actual numeric digit (0–9).
- In the last byte, first 4 bits will store the sign and second 4 bits will store the last numeric digit.
|
Value |
Internal Hex Representation |
|
Unsigned 12345 |
X'F1F2F3F4F5' |
|
+12345 |
X'F1F2F3F4A5' X'F1F2F3F4C5' X'F1F2F3F4E5' |
|
-12345 |
X'F1F2F3F4B5' X'F1F2F3F4D5' |
Sign is stored in the zone portion (high-order 4 bits) of the last byte. Valid signs are given below
|
Sign |
Zone Nibble |
|
Unsigned |
F |
|
Positive |
A,C,E |
|
Negative |
B,D |
01 WS-9 PIC S9(05).
01 WS-X REDEFINES WS-9 PIC X(05).
PROCEDURE DIVISION.
PARA1.
MOVE X'F1F2F3F4F5' TO WS-X
PERFORM CHECK-SIGN
MOVE X'F1F2F3F4A5' TO WS-X
PERFORM CHECK-SIGN
MOVE X'F1F2F3F4C5' TO WS-X
PERFORM CHECK-SIGN
MOVE X'F1F2F3F4E5' TO WS-X
PERFORM CHECK-SIGN
MOVE X'F1F2F3F4B5' TO WS-X
PERFORM CHECK-SIGN
MOVE X'F1F2F3F4D5' TO WS-X
PERFORM CHECK-SIGN
GOBACK.
CHECK-SIGN.
IF WS-9 > 0
DISPLAY WS-9 ' POSITIVE'
ELSE
IF WS-9 = 0
DISPLAY WS-9 ' ZEROS'
ELSE
DISPLAY WS-9 ' NEGATIVE'
END-IF
END-IF.
ADD 1 TO WS-9
DISPLAY 'WS-X : ' WS-X.
|
Output of the program is given below |
Hex value for the number displayed |
|
12345 POSITIVE |
X'F1F2F3F4F5' |
|
WS-X : 1234F |
X'F1F2F3F4C6' |
|
1234v POSITIVE |
X'F1F2F3F4A5' |
|
WS-X : 1234F |
X'F1F2F3F4C6' |
|
1234E POSITIVE |
X'F1F2F3F4C5' |
|
WS-X : 1234F |
X'F1F2F3F4C6' |
|
1234V POSITIVE |
X'F1F2F3F4E5' |
|
WS-X : 1234F |
X'F1F2F3F4C6' |
|
1234§ NEGATIVE |
X'F1F2F3F4B5' |
|
WS-X : 1234M |
X'F1F2F3F4D4' |
|
1234N NEGATIVE |
X'F1F2F3F4D5' |
|
WS-X : 1234M |
X'F1F2F3F4D4' |
Typical packed decimal declarations in COBOL are shown
below:
01 WS-NUMBER1 PIC 9(5) COMP-3.
-> Unsigned packed decimal
- Each byte has two decimal digits except the last byte
- In the last byte, first 4 bits will store the numeric digit and second 4 bits will store the sign.
- If an odd number of digits exists, the unused high-order nibble is padded with zero.
|
Value |
Internal Hex Representation |
|
Unsigned 12345 |
X'12345F' |
|
+12345 |
X'12345A' X'12345C’ X'12345E’ |
|
-12345 |
X'12345B' X'12345D’ |
|
+123456 |
X’0123456C’ |
Similar to zoned decimal, system always uses “C” for positive signs and “D” for negative signs for packed decimals, but still accepts A,B,E signs
01 JUNK PIC X(04).
01 WS-ZONED-DECIMAL REDEFINES JUNK PIC 9(04).
PROCEDURE DIVISION.
MOVE 'ABCD' TO JUNK.
DISPLAY 'WS-ZONED-DECIMAL: ' WS-ZONED-DECIMAL
ADD 1 TO WS-ZONED-DECIMAL
DISPLAY 'WS-ZONED-DECIMAL: ' WS-ZONED-DECIMAL
MOVE X'1A1B1C1D' TO JUNK.
DISPLAY 'WS-ZONED-DECIMAL: ' WS-ZONED-DECIMAL
ADD 1 TO WS-ZONED-DECIMAL
DISPLAY 'WS-ZONED-DECIMAL: ' WS-ZONED-DECIMAL
GOBACK.
WS-ZONED-DECIMAL: 1235
WS-ZONED-DECIMAL: X'1A1B1C1D'
Code Explanation
Mainframe does not have any instruction to perform arithmetic operations on zoned decimals. So, it first converts zoned-decimals to packed-decimal and then performs arithmetic operations on the packed-decimal.
The first move indirectly populated ‘ABCD’(hex value X’C1C2C3C4’) to WS-ZONED-DECIMAL.
Before adding one to WS-ZONED-DECIMAL, Value X’C1C2C3C4’ need to be converted to packed-decimal.
How Zoned Decimal to Packed Decimal Conversion Works
During the conversion process:
- The digit portion of each zoned-decimal byte is treated as a numeric digit.
- The zone bits are ignored except in the rightmost byte.
- The zone bits of the last byte become the sign nibble.
- Digits are packed together from left to right.
- If the packed-decimal result contains an unfilled nibble, it is padded with zero on the left.
Example 1: ‘ABCD’ - X'C1C2C3C4'
Value X’C1C2C3C4’ becomes X‘01234C’ after zoned-decimal to packed-decimal conversion.
Therefore, the second DISPLAY statement shows 1235, because the temporary packed-decimal representation (X'01234C') was successfully incremented by one during the arithmetic operation.
Example 2: X'1A1B1C1D'
Value X'1A1B1C1D' becomes X‘0ABCD1’ after zoned-decimal to packed-decimal conversion.
Since X‘0ABCD1’ does not adhere to packed-decimal representation, when we tried to add one to it, system produced S0C7 abend
As discussed earlier, a packed-decimal field must conform to the valid packed-decimal format. If the field contains invalid digits or an invalid sign nibble and an arithmetic operation is attempted on it, the processor detects the invalid data and raises an S0C7 (Data Exception) abend.