Showing posts with label static SQL. Show all posts
Showing posts with label static SQL. Show all posts

Thursday, 9 July 2026

Db2 Schemas Guide: Qualifiers, CURRENT SCHEMA, and COBOL SQL

A COBOL program can pass bind, compile, and link-edit, then still fail at runtime with SQLCODE -204 because Db2 looked for the table under the wrong qualifier. The SQL text says SELECT * FROM EMPLOYEE, but Db2 might resolve that unqualified table name as PAYROLL.EMPLOYEE, DEV01.EMPLOYEE, or another schema depending on the execution context.

A Db2 schema is a logical owner or namespace for database objects. Tables, views, indexes, aliases, triggers, routines, sequences, and other objects live under a schema name. In production COBOL SQL, the schema is not just a catalog detail. It controls name resolution, migration safety, package promotion, and the difference between testing against the intended table and testing against a same-named object in another environment.

Db2 schema qualifier mapping tables views indexes and object names
A schema qualifies Db2 object names before SQL is executed.

Last updated: July 2026.

What a Db2 Schema Does

A schema groups objects under a qualifier. The fully qualified form is:

schema_name.object_name

For example, PAYROLL.EMPLOYEE and CLAIMS.EMPLOYEE can both exist because the schema names are different. The object name alone is the same, but the fully qualified names point to different objects.

Object reference Meaning Production risk
EMPLOYEE Unqualified table name. Db2 must infer the schema. Can resolve differently across test, QA, and production.
PAYROLL.EMPLOYEE Qualified table name. The schema is explicit. Safer for shared subsystems and promotion paths.
SET SCHEMA = 'PAYROLL' Sets the schema used for unqualified dynamic SQL names. Must be controlled in every code path that prepares SQL.

Schema Versus Database, Table Space, and Owner

Mainframe teams sometimes mix schema, database, table space, and owner because all four can appear near the same object. They are not the same thing.

  • Schema: the qualifier used in SQL object names, such as PAYROLL in PAYROLL.EMPLOYEE.
  • Database: a Db2 container for objects such as table spaces and indexes.
  • Table space: the storage structure that holds table data. See the related Db2 table spaces guide.
  • Authorization ID or owner: the ID or role associated with object creation and privileges.

A schema can look like an owner because many sites create objects under an authorization ID, but production rules should still name the concept clearly. When an abend ticket says "wrong database," but the failing SQL references an unqualified table, the first check is usually schema resolution.

How Db2 Resolves Unqualified Names

When SQL names an object without a qualifier, Db2 applies name-resolution rules. Static SQL and dynamic SQL are not always handled the same way, so a COBOL program can behave differently depending on whether a statement is embedded and bound in a package or prepared at runtime.

For dynamic SQL, IBM documents the CURRENT SCHEMA special register as the schema used to qualify unqualified object references in dynamically prepared statements. That makes CURRENT SCHEMA a real production setting, not a theory question.

SET SCHEMA = 'PAYROLL';

SELECT EMPNO, LASTNAME
  FROM EMPLOYEE
 WHERE DEPTNO = 'A00';

After the SET SCHEMA, the unqualified EMPLOYEE reference is resolved under PAYROLL for dynamic SQL. Many shops still prefer explicit qualifiers in production SQL because the qualifier is visible in the statement, the bind review, and the incident ticket.

CREATE SCHEMA Example

The basic DDL is short:

CREATE SCHEMA PAYROLL;

CREATE TABLE PAYROLL.EMPLOYEE
 (EMPNO     CHAR(6)     NOT NULL,
  LASTNAME  VARCHAR(30) NOT NULL,
  DEPTNO    CHAR(3)     NOT NULL,
  PRIMARY KEY (EMPNO));

The important part for COBOL developers is not the first line alone. It is the later discipline of using the same qualifier in DCLGEN, embedded SQL, bind jobs, catalog checks, and operations runbooks.

COBOL and Static SQL Example

A static SQL cursor in a COBOL program should make the target object clear. In regulated shops, this helps code review because the package points at the expected application schema.

EXEC SQL
    DECLARE C1 CURSOR FOR
        SELECT EMPNO, LASTNAME, DEPTNO
          FROM PAYROLL.EMPLOYEE
         WHERE DEPTNO = :WS-DEPTNO
END-EXEC.

If the program uses DCLGEN copybooks, keep the schema naming policy consistent with the copybook generation process. A DCLGEN made from PAYROLL.EMPLOYEE but used with SQL that references only EMPLOYEE can hide a promotion error until bind or execution. For the full compile and bind path, see the Db2 application environment guide.

Common SQLCODE -204 Scenario

SQLCODE -204 is often the first visible symptom of a schema problem. A batch job might fail in QA with a message that the object is undefined. The table exists, the DBA can query it, and the developer can see it in the catalog. The mismatch is usually that Db2 looked for QAUSER.EMPLOYEE while the real table is PAYROLL.EMPLOYEE.

-- Failing dynamic SQL path
SELECT EMPNO FROM EMPLOYEE;

-- Confirm intended object in the catalog
SELECT CREATOR, NAME, TYPE
  FROM SYSIBM.SYSTABLES
 WHERE NAME = 'EMPLOYEE';

Use the Db2 catalog guide to verify the object owner and type. Then check whether the SQL should use an explicit qualifier, whether SET SCHEMA is missing, or whether the package was bound under the wrong qualifier rules.

Schema Checks Before Promotion

Before moving a COBOL Db2 change from test to production, add schema checks to the same review as package, plan, and collection checks.

  • Search embedded SQL for unqualified tables, views, aliases, sequences, and routines.
  • Compare DCLGEN source against the schema used by the target package.
  • Confirm bind jobs use the expected collection and qualifier settings.
  • Run catalog queries for same-named objects under different schemas.
  • For dynamic SQL, verify any SET SCHEMA path runs before PREPARE.
  • Check SQLCODE handling so -204, -551, and related errors are logged with the resolved object name when available.

Those checks belong near the bind and deployment controls covered in the Db2 packages guide and the Db2 DSN command reference.

When to Use Explicit Qualifiers

Use explicit qualifiers when the SQL targets shared production objects, when the subsystem contains multiple application schemas, or when the statement is reviewed by operations during an incident. A qualified name gives the reviewer one less variable to infer.

Unqualified names can still be acceptable in controlled dynamic SQL frameworks where the application sets CURRENT SCHEMA deliberately and logs that setting. The rule should be written down. If developers have to guess, the next promotion will repeat the same -204 investigation.

FAQ

Is a Db2 schema the same as a database?

No. A schema is a SQL namespace or qualifier for objects. A database is a Db2 container used with storage structures such as table spaces.

Why does the same COBOL SQL work in test but fail in production?

One common reason is unqualified object names. Test might resolve EMPLOYEE under one schema while production expects PAYROLL.EMPLOYEE.

Should COBOL programs qualify every table name?

For production static SQL, explicit qualifiers are usually easier to review and troubleshoot. Some sites rely on bind or dynamic SQL settings, but the rule must be consistent.

Does SET SCHEMA affect static SQL?

Treat SET SCHEMA mainly as a dynamic SQL control. Static SQL is resolved through precompile and bind rules, so check the package and bind settings instead of assuming a runtime SET SCHEMA will fix it.

Practical Rule

When a Db2 object name can exist in more than one place, qualify it or prove which schema Db2 will use. That one check prevents many late-night SQLCODE -204 calls.

Saturday, 17 August 2013

Db2 Binding an Application: COBOL DBRM, Package, Plan, and Run JCL


Db2 application bind checklist from COBOL source to DBRM package plan and run JCL
Bind the DBRM before the program runs.

A COBOL program with embedded SQL does not run against Db2 just because the load module was created. The SQL has to be precompiled into a DBRM, the program has to be compiled and link-edited, and Db2 must have a package or plan that matches what the program calls at run time.

That is the point of application binding. It connects the program's static SQL to Db2 access paths before the batch job, CICS transaction, or IMS program reaches production.

Where binding fits in the COBOL build

A typical static SQL build has four moving parts. If one of them is missing or from the wrong compile, the job can fail even when the COBOL source looks correct.

Build part What it creates Why it matters
Db2 precompile Modified COBOL source and a DBRM member The DBRM contains the static SQL that Db2 will bind.
COBOL compile Object module The embedded SQL calls have already been replaced with host-language calls.
Link-edit Executable load module The load module calls the Db2 language interface at run time.
Bind Package and plan entries in Db2 Db2 stores executable forms of the SQL statements and the selected access paths.

Precompile creates the DBRM

The Db2 precompiler reads the COBOL source and finds each EXEC SQL block. It checks SQL syntax, handles host variable references, includes members such as SQLCA or DCLGEN copybooks when requested, and writes a DBRM member to a partitioned data set.

The DBRM is not the same as the COBOL object module. It is the Db2-side input for binding. In many shops the member name matches the program name, such as PAYRPT01, because that makes the bind JCL and promotion controls easier to audit.

//PC.SYSIN    DD  DSN=APP.SOURCE(PAYRPT01),DISP=SHR
//PC.SYSCIN   DD  DSN=APP.WORK.COBOL(PAYRPT01),DISP=SHR
//PC.DBRMLIB  DD  DSN=APP.DBRMLIB(PAYRPT01),DISP=SHR

Bind the package from the DBRM

For most production applications, bind the DBRM as a package and include the package in a plan. A package keeps the bind unit close to one program module, so a change to one COBOL program does not force every related DBRM in a large plan to be rebound.

BIND PACKAGE(APP01)
  MEMBER(PAYRPT01)
  ACTION(REPLACE)
  ISOLATION(CS)
  CURRENTDATA(NO)
  QUALIFIER(PROD)

The exact bind options depend on the shop standard and workload. For example, a read-only reporting program may use different lock and isolation choices from an update program that posts end-of-day financial rows. Do not copy a bind card from another application without checking the program's SQL behavior.

Bind the plan used by run JCL

The application plan tells the run command which packages can be used. A common pattern is to bind packages into a collection and then bind a plan with a package list.

BIND PLAN(PAYPLAN)
  PKLIST(APP01.PAYRPT01)
  ACTION(REPLACE)

Some sites use a wildcard package list such as APP01.* for a controlled collection. That can reduce plan maintenance, but it should still be managed by promotion rules so test packages do not accidentally become callable from production jobs.

Run JCL must point to the right plan

After compile, link-edit, package bind, and plan bind, the batch job still has to call the expected plan. A typical DSN run step names the Db2 subsystem, program, plan, and application load library.

//RUNSQL  EXEC PGM=IKJEFT01
//STEPLIB DD  DSN=DSN.V12.SDSNLOAD,DISP=SHR
//SYSTSIN DD  *
  DSN SYSTEM(DSN1)
  RUN PROGRAM(PAYRPT01) PLAN(PAYPLAN) -
      LIB('APP.PROD.LOADLIB')
  END
/*
//SYSPRINT DD SYSOUT=*

If the run step names an old plan, a test collection, or the wrong load library, the program may call a package that does not match the current DBRM. That is why a release checklist should compare the load module, DBRM member, package bind, plan bind, and run JCL before the job is released.

Common bind failures and runtime clues

Binding problems usually show up in the bind output, Db2 messages, or SQLCODE returned to the program. The exact message text matters, so always check the Db2 output from the failing job before changing bind options.

Symptom Likely area to check
Bind fails because a table or view cannot be found Check the qualifier, owner, current environment, and whether the object exists in that subsystem.
Bind fails because the user is not authorized Check package, plan, table, view, and execute privileges for the bind owner.
Runtime SQLCODE points to package not found Check package collection, plan package list, subsystem, and whether the package was promoted.
Runtime SQLCODE points to timestamp or consistency mismatch Check whether the load module and DBRM/package came from the same precompile.

Application bind checklist

  • Use the DBRM created from the same source version that produced the load module.
  • Keep DBRM library, load library, package collection, and plan name visible in promotion records.
  • Bind changed programs as packages instead of rebinding a large plan directly from many DBRMs.
  • Review QUALIFIER, OWNER, VALIDATE, isolation, and current data options against the application type.
  • Confirm the run JCL names the intended plan and load library before moving the job to production.

Related DB2 topics

Application binding sits close to several other Db2 topics. Review Db2 Binding and Rebinding for package and plan maintenance, Db2 Packages for package structure, Db2 Objects for database object context, and Db2 SQL Optimization Tips for COBOL Programs for access path review.

FAQ

Is a DBRM the same as a package?

No. The DBRM is produced by the precompile step. A package is created when Db2 binds that DBRM into the catalog and directory.

Can a COBOL Db2 program run without a bind?

A static SQL COBOL program needs a valid package or plan before it can run successfully against Db2. Dynamic SQL follows a different prepare path at run time.

Why does a program fail after a successful compile?

The compile only proves the host language build completed. The run can still fail if the DBRM was not bound, the plan does not include the package, or the load module and package do not match.

For production, treat bind output as part of the build evidence. A clean compile without the matching DBRM, package, plan, and run JCL is not enough.

Db2 Packages Guide for COBOL Static SQL


Db2 package flow showing COBOL embedded SQL, DBRM, BIND PACKAGE, package, plan, and REBIND
Db2 packages hold prepared SQL and access paths.

A COBOL program with static SQL does not carry its access path inside the load module. During precompile, Db2 extracts embedded SQL into a DBRM. During bind, Db2 turns that DBRM into a package that records prepared SQL, bind options, authorization context, and the access path chosen for the SQL statements.

This refresh replaces the old C-oriented explanation with a Db2 for z/OS package guide for COBOL teams. It covers DBRMs, collections, packages, plans, BIND PACKAGE, REBIND, and the checks developers should make before promoting a static SQL change.

What Is a Db2 Package?

A Db2 package is a database object that contains the prepared form of static SQL statements from one program or routine. IBM's BIND PACKAGE documentation says the subcommand builds an application package, records the package description in catalog tables, and saves the prepared package in the directory.

For a COBOL application, the package is the Db2-side partner to the compiled and linked load module. If the load module and package do not match the same SQL level, the program can fail or run with the wrong assumptions.

COBOL Static SQL Build Flow

The build path matters because each output has a different job. The COBOL compiler handles host language code. Db2 handles embedded SQL through the DBRM and bind process.

Step Output Why it matters
Precompile Modified COBOL source and DBRM Separates SQL from COBOL source.
Compile and link-edit Load module Creates executable program code.
BIND PACKAGE Package in a collection Prepares static SQL and records access paths.
BIND PLAN or package list Runtime plan reference Connects run unit to packages.

DBRM, Package, Collection, and Plan

These four terms often get mixed together in incident calls. Keep them separate.

Term Meaning Common problem
DBRM Database request module created by precompile. Wrong DBRM library used during bind.
Package Bound SQL from a DBRM or copied package. Package not rebound after SQL or statistics change.
Collection Named group that contains packages. Runtime points to the wrong collection.
Plan Runtime object that can include a package list. Plan does not include the expected package collection.

BIND PACKAGE Example

Site JCL and options vary, but a package bind normally identifies the collection, DBRM member, action, owner or qualifier options, isolation level, and validation behavior.

BIND PACKAGE(ACCTCOLL) -
     MEMBER(ACCTPOST) -
     ACTION(REPLACE) -
     QUALIFIER(ACCT) -
     ISOLATION(CS) -
     VALIDATE(BIND) -
     EXPLAIN(YES)

Do not copy bind options blindly. ISOLATION(UR), RELEASE(DEALLOCATE), VALIDATE(RUN), and REOPT can be correct in one workload and wrong in another. Use the site standard unless there is a documented reason to deviate.

Package and Access Path

For static SQL, the access path is selected at bind or rebind time. That is why a COBOL program can slow down after a package rebind even when source code did not change. New RUNSTATS, index changes, subsystem function level, bind options, and SQL changes can all affect the path.

  • Capture EXPLAIN output when binding important packages.
  • Record the DBRM library, collection, package, and version used in the change.
  • Compare access paths before and after a rebind for high-volume programs.
  • Know the rollback option if the new package performs badly.

The related Db2 SQL Optimization Tips for COBOL Programs article covers access-path investigation in more detail.

REBIND PACKAGE

A rebind rebuilds an existing package using the current environment and selected options. It is common after RUNSTATS, index changes, SQL compatibility changes, or package maintenance. Rebind is powerful because it can improve performance without changing COBOL source, but it can also choose a worse path if statistics or options are wrong.

REBIND PACKAGE(ACCTCOLL.ACCTPOST) -
       APREUSE(WARN) -
       EXPLAIN(YES)

For production packages, make the rebind visible in the change record. Include package name, collection, owner, bind options, reason, expected benefit, and fallback plan.

Common Package Problems

Symptom Likely package issue Check
Program works in test but fails in production. Different collection or missing package. Plan PKLIST, collection, package name, and version.
SQL starts running slowly after maintenance. Access path changed during rebind. EXPLAIN before/after and RUNSTATS timing.
Authorization error appears at bind or run time. Owner or VALIDATE option mismatch. Package owner, binder authority, and object grants.
Old load module calls new SQL package. Promotion mismatch. Load library, DBRM, package timestamp, and change ticket.

Developer Checklist

  • Confirm the DBRM was generated from the same source level as the load module.
  • Confirm the package collection used by the runtime plan.
  • Review bind options with the DBA for high-volume programs.
  • Use EXPLAIN for SQL that can affect batch windows or online response time.
  • Keep package rollback details in the implementation plan.
  • Coordinate package changes with related DB2 Binding and Rebinding procedures.

FAQ

Is a Db2 package the same as a plan?

No. A package contains prepared SQL for a program or routine. A plan is a runtime object that can reference packages through a package list.

When should a package be rebound?

Rebind after relevant SQL, index, statistics, compatibility, or bind-option changes. For critical packages, compare access paths before and after the rebind.

Can a COBOL program run without its package?

No, static SQL needs the corresponding package or plan/package setup at runtime. The load module and Db2 package must be promoted together.

Package work is successful when the COBOL load module, DBRM, package collection, bind options, and access path all line up. Treat the package as part of the application deliverable, not an afterthought.

New In-feed ads