DB2 DCLGEN turns catalog metadata into application declarations. Give it a DB2 for z/OS table or view, a destination member, and a host language; it writes an SQL DECLARE TABLE statement and a matching COBOL, PL/I, C, or C++ structure. This tutorial explains what the output means, how null indicators and SQL TYPE declarations work, how teams manage generated members, and how to regenerate them without turning a routine schema change into a production defect.
DCLGEN means declarations generator. It is a DSN subcommand, not a database utility such as LOAD or REORG. DCLGEN reads the catalog description of one table or view and produces source text. It can run from a foreground or background DSN session, through DB2I, or through the ADMIN_COMMAND_DSN administrative stored procedure when a controlled automation process is appropriate.
The generated DECLARE TABLE is descriptive. It tells the DB2 application preparation process what columns the programmer expects, but it does not create the table and does not replace catalog validation at bind time. The generated host structure gives the application fields with compatible language types and lengths. This saves repetitive typing and, more importantly, reduces errors such as treating a VARCHAR as a simple fixed string or giving a decimal host variable the wrong scale.
The TABLE operand accepts a table name or view name that exists in the DB2 catalog. Prefer a qualified name such as APP.CUSTOMER_ACCOUNT so the result does not depend on the authorization ID used to run DCLGEN. If TABLE is unqualified and OWNER is omitted, DB2 uses the SQL authorization ID as the qualifier. A qualifier inside TABLE takes precedence over OWNER.
A base table is the obvious input when the program works with the complete business object. A view can be a better contract when the application should see a stable subset, renamed columns, or columns assembled from another design. However, DCLGEN describes the view's result columns; it does not explain whether every view column is updatable. The SQL statements and view definition still determine what the program can change.
Remote catalog objects can be identified with the documented ATlocation option. Most teams generate against the development subsystem whose DDL is being promoted. Generating against an unrelated production level can hide pending changes or introduce fields that are unavailable in test, so record the subsystem, location, and object version with the generated member.
| Option | Purpose |
|---|---|
| TABLE | Qualified or unqualified cataloged table or view to describe |
| LIBRARY | Existing sequential data set or partitioned data set member for output |
| LANGUAGE | PLI, C, IBMCOB, or CPP host-language declarations |
| STRUCTURE | Sets the generated host structure name |
| NAMES / COLSUFFIX | Controls generated field names and optional column-name suffixes |
| INDVAR | Requests a corresponding indicator variable array |
| ACTION | ADD a new destination or REPLACE an existing member |
| RMARGIN | Wraps tokens after column 72 (STD) or column 80 (WIDE) |
The output data set must already exist and be accessible. Use ACTION(ADD) when accidental replacement must be prevented and ACTION(REPLACE) in a deliberate regeneration step. STRUCTURE and NAMES are valuable when multiple DCLGEN members appear in one program: predictable prefixes avoid collisions between common column names such as ID, STATUS, or CREATE_TS.
12345678910111213DSN SYSTEM(DB2T) DCLGEN TABLE(APP.CUSTOMER_ACCOUNT) + LIBRARY('TEAM.APP.DCLGEN(CUSTACCT)') + ACTION(REPLACE) + LANGUAGE(IBMCOB) + STRUCTURE(DCL-CUSTOMER-ACCOUNT) + NAMES(CA-) + COLSUFFIX(YES) + INDVAR(YES) + RMARGIN(STD) END /* Verify subsystem, data set, naming rules, and authorization locally. */
Normal output has two useful interfaces. First, EXEC SQL DECLARE identifies the table and lists its columns in SQL terms. Second, a host-language structure maps those columns into fields the program can use. In COBOL, fixed character columns become PICTURE X items, decimal columns become packed decimal pictures, and varying-length columns become groups containing a length field and a data field.
| SQL type | Typical generated form | Meaning |
|---|---|---|
| CHAR(n) | PIC X(n) | Fixed-length character field |
| VARCHAR(n) | Length plus PIC X(n) data | Structured varying-length host variable |
| SMALLINT / INTEGER / BIGINT | Binary numeric field | Current support can generate COMP-5 declarations |
| DECIMAL(p,s) | Packed decimal picture | Precision and scale determine the PICTURE |
| DATE / TIME / TIMESTAMP | Character representation | Length reflects the generated external representation |
| XML | SQL TYPE IS XML AS CLOB(1M) | Generated default can be edited when another size is needed |
Exact output depends on the installed DB2 maintenance level and selected options. Current DB2 12 and DB2 13 maintenance added useful mappings, including COMP-5 generation for integer data and improved DECFLOAT support for PL/I and C. Treat the generated member from your maintained subsystem—not an old training example—as the source of truth for your environment.
1234567891011121314151617EXEC SQL DECLARE APP.CUSTOMER_ACCOUNT TABLE ( CUSTOMER_ID INTEGER NOT NULL, CUSTOMER_NAME VARCHAR(80) NOT NULL, CREDIT_LIMIT DECIMAL(11,2), PROFILE_XML XML ) END-EXEC. 01 DCL-CUSTOMER-ACCOUNT. 05 CA-CUSTOMER-ID PIC S9(9) COMP-5. 05 CA-CUSTOMER-NAME. 49 CA-CUSTOMER-NAME-LEN PIC S9(4) COMP-5. 49 CA-CUSTOMER-NAME-TEXT PIC X(80). 05 CA-CREDIT-LIMIT PIC S9(9)V99 COMP-3. 05 CA-PROFILE-XML USAGE IS SQL TYPE IS XML AS CLOB(1M). * Conceptual shape only; generate from your own maintained subsystem.
The terms SQLTYPE and SQL TYPE IS are easy to confuse. SQLTYPE is also the name of a code field in an SQLDA, where a numeric value describes a dynamic SQL column and whether it can be null. DCLGEN source output normally concerns host declarations instead. For SQL-oriented values that COBOL, PL/I, or C cannot express directly, the generated declaration can use an SQL TYPE IS clause.
IBM documents XML as a clear DCLGEN example: it generates SQL TYPE IS XML AS CLOB(1M). The one-megabyte size is a default for that host variable and can be changed when the program's actual XML requirement is smaller or larger. Similar SQL TYPE syntax is used by application programmers for LOB locators, file reference variables, ROWID, binary values, and other specialized interfaces. Do not replace these declarations with an ordinary character field merely because the compiler does not recognize the SQL words; the DB2 precompiler or integrated coprocessor must process them first.
A nullable SQL column needs two pieces of information in a host program: its value and whether the value is null. COBOL has no ordinary data value equal to SQL NULL, so DB2 uses a small integer indicator variable. A negative indicator means null on input or reports null on output. Zero normally means a non-null value. A positive output indicator can communicate conditions such as truncation, depending on the operation and data type.
INDVAR(YES) asks DCLGEN to create an indicator array corresponding to the host-variable structure. Generation alone does not attach indicators magically to every SQL reference. The programmer still writes the correct indicator after the host variable, verifies its position, and initializes it before input. Named indicator fields are often clearer than positional array elements, so some teams generate the array and then expose approved names in a maintained wrapper.
123456789101112EXEC SQL SELECT CREDIT_LIMIT INTO :CA-CREDIT-LIMIT :CA-IND-CREDIT-LIMIT FROM APP.CUSTOMER_ACCOUNT WHERE CUSTOMER_ID = :CA-CUSTOMER-ID END-EXEC. IF CA-IND-CREDIT-LIMIT < 0 MOVE ZERO TO CA-CREDIT-LIMIT MOVE 'Y' TO WS-CREDIT-LIMIT-IS-NULL END-IF
DCLGEN works just as well for a table designed by your organization as for an IBM sample table. A custom DCLGEN table should mean a normal, cataloged application table or view with a deliberate interface—not a private metadata table that DCLGEN reads instead of the DB2 catalog. Use a schema-qualified name, stable column naming, and a structure prefix tied to the application.
If a program uses only five columns from a fifty-column table, generating all fifty may create an unnecessarily broad coupling. One approach is to create an approved application view containing the intended interface and run DCLGEN for that view. Another is to maintain a smaller hand-written host structure, but then the team accepts responsibility for every type and length. The view approach keeps generation tied to catalog metadata while making the contract explicit.
Do not use a custom table as a substitute for dynamic metadata discovery. Programs that must describe unknown result sets at run time use DESCRIBE and an SQLDA; DCLGEN is for a known compile-time object interface.
The standard DCLGEN syntax has no general-purpose TEMPLATE operand. Native formatting and naming controls include STRUCTURE, NAMES, COLSUFFIX, LABEL, INDVAR, DBCS options, and RMARGIN. When a shop says “DCLGEN template,” it usually means a maintained JCL skeleton, REXX wrapper, pipeline step, or source member convention that supplies those documented options consistently.
A useful template records environment placeholders, table qualifier, destination library, language, structure prefix, indicator policy, and ADD-versus-REPLACE behavior. Keep the generated block separate from hand-written additions. If a site needs aliases, validation fields, or comments not produced by DCLGEN, put them in a wrapper copybook or run a reviewed, deterministic post-processing step. Hand edits buried inside generated output disappear at the next regeneration.
Store the generated declarations in a library available to the DB2 precompiler or integrated coprocessor. The program uses the same member name from the DCLGEN LIBRARY operand in an SQL INCLUDE statement. INCLUDE is expanded during DB2 application preparation, so it must appear where the resulting host-language and SQL declarations are valid—normally the COBOL DATA DIVISION's WORKING-STORAGE or LINKAGE section.
12345678910DATA DIVISION. WORKING-STORAGE SECTION. EXEC SQL INCLUDE CUSTACCT END-EXEC. EXEC SQL INCLUDE SQLCA END-EXEC.
SQL INCLUDE is not the same as a COBOL COPY processed independently before DB2 sees the SQL. Use the preparation method standardized by your build. Verify concatenation order when two libraries contain the same member name; otherwise a successful compile can silently use an obsolete declaration.
A generated member is still a versioned application interface. Store it in source control when your build and audit practices permit, along with the exact DCLGEN command, source object, subsystem level, and any deterministic post-processing. This lets a code review show that CUSTOMER_NAME changed from VARCHAR(40) to VARCHAR(80), a new nullable column appeared, or a decimal scale changed.
Avoid regenerating all DCLGEN members automatically during every build. That makes the compile depend on whichever catalog happens to be reachable and can introduce unreviewed interface changes. A safer pipeline has an explicit generation stage that produces a diff and fails when output changes without an approved schema update.
Check the subsystem, location, qualifier, and authorization ID. A missing qualifier can resolve to the runner's ID instead of the application schema. Fully qualify TABLE and verify that the object exists in that catalog.
The DCLGEN process needs an appropriate privilege set, such as ownership or SELECT on the table or view, DBADM on its database, or suitable system authority. Do not solve a development generation failure by granting broad production authority; use the least-privileged generation identity approved by the site.
LIBRARY must identify an existing accessible sequential or partitioned data set. ADD fails when the member already exists; REPLACE is required for intentional replacement. Check quoting because an unquoted library name can be expanded using the user prefix and language conventions.
Column names with special characters, embedded blanks, or excessive length can be invalid in a host language even though they are legal SQL identifiers. Use NAMES, STRUCTURE, and COLSUFFIX thoughtfully. COBOL underscores are translated to hyphens. RMARGIN(STD) wraps after column 72, while WIDE wraps after column 80; match the source format accepted by the downstream toolchain.
Confirm that the DB2 precompiler or integrated coprocessor is processing the source before the ordinary compiler treats SQL TYPE text as COBOL, PL/I, or C. Also verify that the selected host-language level and DB2 maintenance support the source data type.
Regenerate and compare. Then rebuild and rebind the affected application. DCLGEN itself does not discover which programs use the member, and REBIND alone does not resize an old COBOL field. Maintain dependency information so schema reviews identify every include consumer.
Imagine a DB2 table is a tray with spaces for a name, a number, and a date. Your COBOL program needs its own tray with spaces of exactly the right shapes. DCLGEN looks at the DB2 tray and draws a matching tray for COBOL. If a space is allowed to be empty, DCLGEN can also draw a little yes-or-no flag called an indicator. The drawing does not build or change the real tray. When someone changes the real tray, you make a new drawing, compare it with the old one, and test that your program still puts everything in the right place.
1. What are the two main parts of normal DCLGEN output?
2. What can be specified as DCLGEN input?
3. What does INDVAR(YES) request?
4. Why should a DCLGEN member be regenerated after a relevant schema change?
5. Which statement normally brings a DCLGEN library member into an application?
6. Does the standard DCLGEN command provide a general custom TEMPLATE option?