Thursday, May 14, 2026
DB2 SQL to find tables used by a program
Thursday, April 23, 2026
Defining GDGs with more than 255 generations
LIMIT(limit)
Specifies the maximum number, from 1 to 255, of GDSs that can be associated with the GDG being defined. If EXTENDED is specified, 1 to 999 GDSs can be associated with the GDG being defined.
EXTENDED|NOEXTENDED
Specifies whether the GDG is to be an extended GDGr or not.
EXTENDED
allow up to 999 generation data sets (GDSs) to be associated with the GDG.
Abbreviation: EXT
allow up to 255 generation data sets (GDSs) to be associated with the GDG. This is the default value.
Abbreviation: NEXT
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
DEFINE GDG(NAME(USERID.GDG.LIMIT999) -
EXTENDED -
LIMIT(999) -
NOEMPTY -
SCRATCH)
/*
Converting a NOEXTENDED GDG to a EXTENDED GDG
- Define a temporary user
catalog.
- REPRO MERGECAT the GDG
from the original user catalog to the temporary user catalog. This moves
the GDG and all GDSes to the temporary user catalog and removes them from
the original user catalog.
- DEFINE a new GDG with
the same name as the original GDG specifying the EXTENDED parameter and a
new LIMIT parameter as desired.
- REPRO MERGECAT only the
GDSes using wild card notation from the GDG in the temporary user catalog
into the new GDG now in the original user catalog.
- Use DELETE RECOVERY to
delete the temporary user catalog.
The process is complete. You can use LISTCAT to prove that the new GDG has the EXTENDED attribute and that a new LIMIT has been set.
//*
//CONVERT EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
/* 1. DEFINE A TEMPORARY CATALOG */
UCAT -
(NAME (TEMP.UCAT) STORCLAS(SMSSTORC) -
CYL (1 1))
INDATASET(ORIG.CAT) -
OUTDATASET(TEMP.UCAT) -
ENTRIES(SMSA.GDG) -
MERGECAT
EXTENDED LIMIT(999) SCRATCH PURGE)
INDATASET(TEMP.UCAT) -
OUTDATASET(ORIG.CAT) -
ENTRIES(SMSA.GDG.*) -
MERGECAT
/* LISTCAT TO SHOW EVERYTHING BUILT CORRECTLY */
/*
Saturday, April 18, 2026
Limiting Storage use above the bar in z/Architecture
As in the 31-bit address space, a virtual "line" marks the 16-megabyte address. The 64-bit address space also includes the virtual line at the 16-megabyte address; additionally, it includes a second virtual line called the bar that marks the 2-gigabyte address. The bar separates storage below the 2-gigabyte address, called below the bar, from storage above the 2-gigabyte address, called above the bar. The area above the bar is intended for data; no programs run above the bar. There is no area above the bar that is common to all address spaces, and no system control blocks exist above the bar. You can set a limit on how much virtual storage above the bar each address space can use. This limit is called the MEMLIMIT . If you do not set MEMLIMIT, the system default is 0, meaning no address space can use virtual storage above the bar (Use of real storage above the 2GB is not controlled by this parameter). If you want to use virtual storage above the bar, you need to set the MEMLIMIT explicitly. You can set an installation default MEMLIMIT through SMFPRMxx in PARMLIB. You can also set MEMLIMIT for a specific address space in the JCL that creates the address space or by using SMF exit IEFUSI.
To use virtual storage above the bar, a program must request storage above the bar, be in AMODE 64 and use the new z/Architecture assembler instructions.
SMF MEMLIMIT Parameter
An installation can set the default MEMLIMIT through SMFPRMxx in PARMLIB.
MEMLIMIT(NOLIMIT)
nnnnnM
nnnnnG
nnnnnT
nnnnnP
This specifies the default MEMLIMIT to be used by jobs not establishing a MEMLIMIT in their JCL. For reference see z/OS MVS JCL User's Guide . NOLIMIT means that there is no limit on the use of virtual storage above 2 gigabytes.
MEMLIMIT values are defined with nnnnnM for megabytes, nnnnnG for gigabytes, nnnnnT for terabytes, or nnnnnP for petabytes. For example, to request 1200 gigabytes, you can specify MEMLIMIT(1200G). D SMF,O operator command displays the current MEMLIMIT, as shown in example below:
RESPONSE=SYSA
IEE967I 15.39.05 SMF PARAMETERS 795
MEMBER = SMFPRMZ3
MULCFUNC -- DEFAULT
MEMLIMIT(00000M) -- DEFAULT
DDCONS(YES) -- DEFAULT
LASTDS(MSG) -- DEFAULT
NOBUFFS(MSG) -- DEFAULT
DUMPABND(RETRY) -- DEFAULT
SUBSYS(OMVS,NODETAIL) -- SYS
SUBSYS(OMVS,TYPE(0,30,70:79,88:90,103,245)) -- PARMLIB
SUBSYS(OMVS,INTERVAL(SMF,SYNC)) -- PARMLIB
SUBSYS(OMVS,NOEXITS) -- PARMLIB
SUBSYS(STC,NODETAIL) -- SYS
Note: If MEMLIMIT is not specified in SMFPRMxx, the default value is 0M.
MEMLIMIT on JOB and EXEC Statement
MEMLIMIT is a new keyword on the JOB and EXEC statements. MEMLIMIT specifies the limit on the total number of usable virtual storage above the bar for a single address space.
While there is no practical limit to the virtual storage above the bar, there are practical limits to the real storage frames and auxiliary storage slots backing the virtual storage area. To control the amount of real and auxiliary storage an address space can use for memory objects at one time, your installation should establish an installation default MEMLIMIT to set the total amount of usable virtual pages above the bar for a single address space. You set this default on the MEMLIMIT parameter in the SMFPRMxx parmlib member, or through the SET SMF or SETSMF commands. This default takes effect if a job does not specify MEMLIMIT on the JOB or an EXEC statement or REGION=0M in the JCL; the MEMLIMIT specified in an IEFUSI exit routine overrides all other MEMLIMIT settings.
The system enforces the MEMLIMIT when you issue the IARV64 GETSTOR and CHANGEGUARD services. When your unconditional request for new storage (either for a new memory object or for more usable storage in an existing memory object) causes the MEMLIMIT to be exceeded, the system abends the program. IBM recommends programs use the COND parameter to make a conditional request and check the return code to make sure the storage is available.
What happens to the MEMLIMIT for an already-created address space if a SET SMF or SETSMF command changes the default MEMLIMIT (either the system default or the installation default)?
If the command raises the current default MEMLIMIT, all address spaces whose MEMLIMIT was set through SMF run with the higher default.
If the command lowers the current default MEMLIMIT, all address spaces whose MEMLIMIT was set through SMF keep their original system default.
A SET SMF or SETSMF command cannot change the MEMLIMIT value set through JCL or by an IEFUSI installation exit.
MEMLIMIT Enforcement Through IEFUSI
The SMF IEFUSI exit can change the MEMLIMIT value by updating the value in the third double word. But the publication failed to mention the value used is in the unit of MB (for example, 00000000 00008400 is 33 GB).
The z/OS 1.2 MVS Installation Exits manual does not describe the meaning of the flags in the first double word. The z/OS 1.2 book contains a NOLIMIT value of FFFFFFFF FFFFF000, which is incorrect. Both of these errors have been corrected in the z/OS 1.3 publication. The z/OS 1.2 and z/OS 1.3 books do not mention the unit of MB in the third double word
When IEFUSI Exit receives control, Register 1 points to a list of addresses. Word 9 contains the address of an area, as described in the z /OS 1.3 MVS Installation Exits :
Word 9
The address of an area consisting of three 64-bit
fields:
| A 64-bit flagword. The first 8 bits indicate
whether the
| source of the MEMLIMIT is from JCL or the
SMF-supplied
| system default. The remaining 56 bits are not
used. Possible
| values for the first 8 bits, and their meanings
are as
| follows:
| 01 -- indicates MEMLIMIT is from SMF
| 02 -- indicates MEMLIMIT is from JCL
| 03 -- indicates MEMLIMIT was set to NOLIMIT
because JCL
| specified REGION=0
| FF -- indicates MEMLIMIT is from SMF (indicative
of
| internal processing errors)
| Note: Other values are possible when initializing
a child
| address space in the UNIX System Services
| environment. See UNIX System Services
publications
| for more information.
| The 64-bit MEMLIMIT originally requested by the
source that
| is specified in the flagword.
| The 64-bit MEMLIMIT requested by the IEFUSI exit.
The
| initial value is X'FFFFFFFFFFFFFFFF' to indicate
that no
| value was set by the exit. If not changed, SMF
uses the
| MEMLIMIT that was originally requested.
Note: A MEMLIMIT of NOLIMIT is equivalent to X'00000FFFFFFFF000'.
The REGION JCL Parameter
The REGION JCL Parameter
I have wanted to write this column for a long time. The JCL REGION parameter is one of the most confusing of all JCL parameters. Using it correctly can be crucial to getting vastly improved throughput for many batch jobs. The confusion about the REGION parameter stems from many factors. Some are historical. Others are due to misconceptions. I will attempt to explain as many of these factors as possible and hopefully, clarify the REGION parameter's usage.
REGION does NOT acquire storage
This is the first misunderstanding that needs clarification. I'll state this as: If a REGION= parameter is coded in a JCL stream or at TSO logon, this DOES NOT cause any storage to be acquired by the operating system. Or, if I code "REGION=0M" on a job card, my job does NOT attempt to GETMAIN all of the virtual storage on the operating system.
Coding a REGION parameter influences only two data values within a control block known as the Local Data Area (LDA, DSECT IHALDA). These two binary fullword values store the maximum amount of virtual storage that address spaces can GETMAIN. Be clear on this: Programs being executed acquire storage. Not the JCL itself.
Why two values? Simple. One field stores the 24-bit ("below the 16 megabyte line") maximum and the other stores the 31-bit ("above the 16 megabyte line") maximum. This dual nature of the REGION parameter, limiting both 24 and 31 bit storage, is critical and will be fully explained later.
Jobcard Coded REGION Overrides Step-Coded REGION
At first, this might seem a bit upside down. Doesn't coding a STEPLIB override any JOBLIB that might be coded? It seems natural that a step-coded value would override the global declaration from the jobcard.
It doesn't work that way. The STEPLIB/JOBLIB situation is an exception. If you code a REGION=50M on your jobcard, it will apply to all steps in the job – even steps that code a different REGION value.
Knowing that the REGION declaration doesn't actually acquire any storage but instead, establishes a limit, I recommend always coding REGION on the jobcard.
Defaults and Exits
This is where the REGION processing gets tricky. I am going to try to explain this as clearly as possible but be forewarned: The defaults and exit-modified values for REGION vary widely from installation to installation. I can't speak to absolutes here because every single z/OS site usually has a different set of default values.
To begin, ask yourself: What if a REGION parameter is not even coded? What limiting values will end up in the LDA? Figure 1 describes how to use the BROWSE command of DDLIST under TSO/ISPF to locate and examine the LDA for your TSO session.
What is the default for REGION?
All REGION discussion that follows applies to what are known as "V=V (or ADDRSPC=VIRT) type of job steps – 99.999% of all work on z/OS.
There is a single question to ask and get answered before you can accurately determine the default limiting amounts for REGION at your site. That question is:
Has your installation established their own defaults by way of either the IEFUSI or IEALIMIT exits? Or, have IBM's "factory defaults" been left in place?
REGION Values Fall Into Ranges
Much of the following discussion is based upon the explanations in Section 16.13.3 – REGION Defaults – in the z/OS V1R6 MVS JCL Reference manual. I suggest reading this bit of IBM documentation in conjunction with my explanations. I have tried to simplify things a bit and to underscore the fact that the values coded on a REGION parameter fall into ranges when it comes to what type of REGION you are seeking to limit.
REGION=0M or REGION=0K
The value of zero is a special case. Coding a zero REGION size sets the limits to all of the 24-bit and 31-bit virtual storage available to the address space. Typical defaults are between 8M-10M for 24-bit storage and between 1600M-1900M for 31-bit storage. It DOES NOT acquire any memory and may be further limited by an IEALIMIT or IEFUSI exit.
Also, remember that the REGION parameter applies only to virtual storage limits for the address space (job, step, TSU, etc) that it is coded on. To view the available private storage for an address space (the REGION= amount you can potentially use), you would need an RMF post processor VSTOR report or some other tool that displays a virtual storage map – something like Mark Zelden's IPLINFO REXX exec, TASID, ShowMVS or MXI. If your site has one installed, MVS monitors like OMEGAMON, TMON and MAINVIEW can also display a virtual storage map.
REGION=1K through REGION=16384K
When you code a value between 1K and 16M (note that 16384K = 1,024 X 16), the limit will be applied only to 24-bit storage. For the 31-bit limit, the job will either get the IBM default of 32M or an exit-modified 31-bit limit value.
Note that there is a range of "below the line" limiting values that I will call impossible values. These values fall between approximately REGION=8192K-16384K. If an exit doesn't intercept these impossible values and alter them dynamically (to an amount less than the 24-bit maximum amount), your job will get an S822 abend every time if it uses REGION values in the impossible range. Refer to Figure 2 for a simple piece of JCL to test for the impossible REGION values.
If this one-step IEFBR14 (with no DD names) gets an S822 when using REGION values in the impossible range, this is a good indication that no exits are in place that are dynamically altering REGION limits.
REGION=16385K through REGION=32768K
REGION values between 16M (+ 1K) up to and including exactly 32M limits the job step to the defined site maximum for 24-bit storage. The 31-bit limit will always be either 32M or an exit-modified 31-bit limit value.
REGION=32769K through REGION=2047M
REGION values between 32M (+ 1K) up to and including exactly 2047M limits the job step to the defined site maximum for 24-bit storage. The 31-bit limit will be either the coded value or an exit-modified 31-bit limit value.
In the IBM documentation, the following sentence appears several times when describing how the region below 16 megabytes might be influenced:
"The resulting size of the region below 16 megabytes depends on system options and what system software is installed."
This varies from site to site but a typical default maximum for "below the line" storage is between 9M-10M. In other words, no job step can EVER request more below the line storage than this. If it does, this is considered an impossible REGION value and either your job will abend with an S822 or the impossible value will be lowered by an exit.
Conclusion
Certainly, the REGION parameter of z/OS JCL is one of the most confusing of all JCL parameters. One thing to keep in mind is the very nature of a language such as JCL. JCL, like HTML, is what I call a "static" language. It is designed to create a framework for the invocation of programs, nothing more. It doesn't have the capability of taking its own actions. All of its many keywords and parameters define existing or newly created run-time components. Some JCL parameters set limits or establish other run-time variables but JCL itself has no ability to acquire storage, move values or do anything other than establish a run-time environment for programs.
With this in mind, remember these three key things about how the REGION parameter influences virtual storage in a z/OS JCL stream:
1) It NEVER acquires any storage. It only sets limits.
2) A REGION value coded on the job card overrides any step-coded values.
3) The values coded fall into ranges. Below 16M, the REGION value limits 24-bit storage. Above 32M, you are limiting 31-bit storage.
Figure 1 – Using the BROWSE command of DDLIST to locate and examine the Local Data Area of your TSO session. This chaining can be followed in any z/OS address space to locate and examine the LDA for storage used and maximum allowed. Note that TSO sessions (TSU) usually have a different default for a 24-bit storage limit than stock batch jobs.
· Invoke DDLIST at any ISPF command line.
· Once in DDLIST, type: BROWSE 224. <- period required, at the command line. This is the address of your TSO session's ASCB.
· Type: BROWSE and move the cursor anywhere within the address at +0 on the screen and press enter (a "point-and-shoot" BROWSE). At the next screen, look for the eye-catching literal "ASCB" in the memory translation area.
· Type: BROWSE and move the cursor anywhere within the address at +30 into the ASCB and press enter. The LDA address is typically very high in memory (begins with X'7F').
· You should now be viewing the LDA of your TSO session. Look for the eye-catching literal "LDA" in the memory translation area at the most recent address that you BROWSED.
· The following offsets into the LDA hold the REGION values:
X'D8' – Maximum amount of 31-bit storage allowed for your TSO session
X'F0' – Current amount of used 31-bit storage
X'D0' - Maximum amount of 24-bit storage allowed for your TSO session
X'E8' – Current amount of used 24-bit storage
X'CC' – The REGION value from either a LOGON screen (possibly defaulted) or an exit
Note that all of these values are fullword binary integers that will need to be converted from hex into decimal.
As an experiment, split the screen and get into edit on a large dataset. Return to the LDA display and press enter, watching the value at X'F0' (current amount of used 31-bit storage). Did it increase?
For the full context of the LDA, refer to DSECT IHALDA.
Figure 2 – Testing for impossible REGION values. Begin with a REGION=9000K and then increment the REGION value – either by K or by M. If you do not get an S822 abend, an exit is intercepting and changing the impossible REGION value. No DD names are needed. Simply code an EXEC line naming PGM=IEFBR14 with a REGION parameter. Add a job card but do not code a REGION on the job card.
//add a jobcard
//*
//TESTS822 EXEC PGM=IEFBR14,REGION=9000K
Friday, April 17, 2026
Viewing the IEAOPTxx settings currently in use through RMF Monitor
Monday, April 6, 2026
XCOM Data Transfer experiencing dataset contention
Step 1 – Delete the dataset TEST.XCOM.FILE
Step 2 – Executes some COBOL program to create TEST.XCOM.FILE
Step 3 – Perform XCOM data transfer using TEST.XCOM.FILE
Step 4 – Send an email with TEST.XCOM.FILE as an attachment
- Before a job starts, the initiator issues an ENQ (enqueue) for every dataset used in the job.
- The highest level of control required by any step determines the ENQ type:
- DISP=SHR → Shared (SHR)
- DISP=NEW, MOD, or OLD → Exclusive (EXCL)
- ENQs cannot be downgraded during job execution.
- The ENQ is released only at the end of the last step that references the dataset.
- When the XCOM started task begins the actual transfer, the dataset is no longer held by the job.
- The transfer proceeds without contention.
The ENQ for each dataset is released at the end of the last step of the job referencing it. Since ENQs cannot be downgraded from EXCL to SHR, if one step needs the ENQ EXCL and a following step only needs it SHR, the ENQ is still issued as EXCL and held until the end of the last step which references that data set, at which point the ENQ is released entirely.
Wednesday, February 18, 2026
COBOL Binary search
Tuesday, February 10, 2026
Row-Value-Expression and Quantified Predicates in Db2
Row-Value-Expression in Db2
A row-value-expression allows you to compare multiple columns (or values) at once as a tuple. Instead of writing separate conditions for each column, you can group them together.
General Syntax
(COL1, COL2, COL3) operator (Value1, Value2, Value3)
· Both sides must have the same number of values.
·
Data
types must be compatible.
·
Comparisons
are evaluated pair by pair.
·
If any
comparison involves NULL, the result may be Unknown.
Operators Explained with Examples
1. Equality (=)
(COL1, COL2, COL3) = (100, 'X', 2000)
· Row (100, 'X', 2000) → True
·
Row (100,
'Y', 2000) → False
· Row (100, NULL, 2000) → Unknown
2. Inequality (<>)
(COL1, COL2, COL3) <> (100, 'B', 500)
· Row (100, 'B', 500) → False (all equal)
·
Row (100,
'C', 500) → True (COL2 <> 'B')
·
Row (101,
'B', 500) → True (COL1 <> 100)
3. Less Than (<)
(COL1, COL2, COL3) < (100, 'B', 500)
· Row (100, 'A', 500) → True ('A' < 'B')
·
Row (99,
'Z', 999) → True (99 < 100)
·
Row (100,
'B', 400) → True (400 < 500)
4. Greater Than (>)
(COL1, COL2, COL3) > (100, 'B', 500)
· Row (100, 'C', 500) → True ('C' > 'B')
·
Row (101,
'A', 300) → True (101 > 100)
·
Row (100,
'B', 600) → True (600 > 500)
5. Less Than or Equal (<=)
(COL1, COL2, COL3) <= (100, 'B', 500)
· Row (100, 'B', 500) → True (exact match)
·
Row (100,
'A', 500) → True ('A' < 'B')
·
Row (99,
'Z', 999) → True (99 < 100)
6. Greater Than or Equal (>=)
(COL1, COL2, COL3) >= (100, 'B', 500)
· Row (100, 'B', 500) → True (exact match)
·
Row (100,
'C', 500) → True ('C' > 'B')
·
Row (101,
'A', 300) → True (101 > 100)
The detailed IBM manual can be found at the following link:
Quantified Predicates in Db2
A quantified predicate compares a value (or a row of values) against a set of values returned by a subquery (fullselect). It uses operators together with quantifiers like ALL, SOME, or ANY.
General Syntax
expression operator {ALL | SOME | ANY} (fullselect1)
(row-value-expression) operator {ALL | SOME | ANY} (fullselect2)
· expression → single value compared against a column of values.
·
row-value-expression
→ tuple of values compared against multiple columns.
·
fullselect
→ subquery returning one or more values.
Behavior of Quantifiers
1. ALL
- True if the relationship holds for every
value returned by the subquery.
- False if the relationship fails for at least
one value.
- Unknown if no comparison is false, but at least
one is unknown due to NULL.
- Special case:
If the subquery returns no rows, the result is True.
2. SOME / ANY
- True if the relationship holds for at
least one value returned by the subquery.
- False if the subquery is empty or the
relationship fails for all values.
- Unknown if no comparison is true, but at least
one is unknown due to NULL.
Examples
TBLA
|
COLA |
|
1 |
|
2 |
|
3 |
|
4 |
TBLB
|
COLB |
COLC |
|
2 |
2 |
|
3 |
– |
TBLC
|
COLB |
COLC |
|
2 |
2 |
Example 1: ALL
COLA > ALL (SELECT COLB FROM TBLB UNION SELECT COLB FROM TBLC)
· Subquery returns {2, 3}.
·
Predicate
is False for rows 1, 2, 3.
·
True for row 4 (4 > 2 and 4 > 3).
Example 2: ANY
COLA > ANY (SELECT COLB FROM TBLB UNION SELECT COLB FROM TBLC)
· Subquery returns {2, 3}.
·
Predicate
is False for rows 1, 2.
·
True for rows 3, 4 (3 > 2, 4 > 2 or 3).
Example 3: ALL with NULL
COLA > ALL (SELECT COLC FROM TBLB UNION SELECT COLC FROM TBLC)
· Subquery returns {2, NULL}.
·
Predicate
is False for rows 1, 2.
·
Unknown for rows 3, 4 (because of NULL).
Example 4: SOME with NULL
COLA > SOME (SELECT COLC FROM TBLB UNION SELECT COLC FROM TBLC)
· Subquery returns {2, NULL}.
·
Predicate
is Unknown for rows 1, 2.
·
True for rows 3, 4 (3 > 2, 4 > 2).
Example 5: Empty Result with ALL
COLA < ALL (SELECT COLB FROM TBLB WHERE COLB > 3
UNION
SELECT COLB FROM TBLC WHERE COLB > 3)
· Subquery returns empty set.
·
Predicate
is True for all rows (special case).
Example 6: Empty Result with ANY
COLA < ANY (SELECT COLB FROM TBLB WHERE COLB > 3
UNION
SELECT COLB FROM TBLC WHERE COLB > 3)
· Subquery returns empty set.
·
Predicate
is False for all rows.
The detailed IBM manual can be found at the
following link:
https://www.ibm.com/docs/en/db2-for-zos/12.0.0?topic=predicates-quantified-predicate