Almost every SQL statement you write in DB2 for z/OS can ask the engine for “who am I?”, “what time is it here?”, or “which schema should unqualified names use?” Those answers live in special registers — named session values Db2 keeps for your application process. This page explains what they are, how to reference them in SQL, which ones you can change, and how scope works across programs, stored procedures, and commits.
IBM’s SQL Reference defines a special register as a storage area defined for an application process by Db2 and used to store information that can be referenced in SQL statements. A reference to a special register is a reference to a value provided by the current server. If the value is a string, its CCSID is a default CCSID of that server.
Think of registers as named sticky notes taped to your thread, not as subsystem-wide switches. Two CICS transactions, two TSO users, or two DDF connections each have their own CURRENT SQLID, CURRENT SCHEMA, and CURRENT PATH. Changing yours does not change anyone else’s.
Registers are not host variables. You do not declare them in COBOL. You write the register name in SQL the same way you write a column name or a literal. Db2 substitutes the current value when the statement runs at the server (with a few local exceptions listed later).
| Family | Examples | How you change them |
|---|---|---|
| Datetime | CURRENT DATE, CURRENT TIME, CURRENT TIMESTAMP, CURRENT TIME ZONE | Read-only (clock / PARMLIB) |
| Identity | USER, SESSION_USER, CURRENT SQLID | SQLID yes; USER no |
| Name resolution | CURRENT SCHEMA, CURRENT PATH, CURRENT PACKAGE PATH, CURRENT PACKAGESET | Yes (SET SCHEMA, SET PATH, …) |
| Client info | CURRENT CLIENT_ACCTNG, CURRENT CLIENT_APPLNAME, CURRENT CLIENT_USERID | APIs / WLM, not ordinary SET |
| Acceleration / MQT | CURRENT QUERY ACCELERATION, CURRENT REFRESH AGE, CURRENT ACCELERATOR | Yes |
Later pages in this section walk through client information, schema and authorization, datetime and temporal, and accelerator / materialized-query-table registers. A companion page covers application compatibility, encoding scheme, degree, explain mode, and other “behaviour” registers.
Put the register name anywhere a compatible expression is allowed: SELECT list, WHERE, VALUES, INSERT, default expressions (where the product allows it), and SET assignments into host variables.
1234567SELECT CURRENT SQLID, CURRENT SCHEMA, CURRENT DATE, USER, CURRENT SERVER FROM SYSIBM.SYSDUMMY1; VALUES CURRENT TIMESTAMP; SET :HV-SQLID = CURRENT SQLID;
Underscore spellings match the SQL standard for several registers. These pairs are equivalent on Db2 for z/OS:
USER is a synonym for SESSION_USER. Prefer SESSION_USER in new SQL because that is the preferred spelling in the SQL Reference.
Reading is always the register name in an expression. Changing a register, when it is allowed, uses a dedicated SET statement — not an assignment like SET CURRENT DATE = …, which is invalid.
1234SET CURRENT SQLID = SESSION_USER; SET SCHEMA = 'HR'; SET PATH = HR, SYSTEM PATH; SET CURRENT QUERY ACCELERATION NONE;
Registers you cannot SET with SQL include CURRENT DATE, CURRENT TIME, CURRENT TIMESTAMP, CURRENT TIME ZONE, CURRENT MEMBER, USER / SESSION_USER, and the client-info family (those last ones are filled by attachment APIs, JDBC setClientInfo, RRSAF SIGNON, or WLM_SET_CLIENT_INFO). CURRENT SERVER changes when a CONNECT statement succeeds, not via SET CURRENT SERVER.
In distributed applications, CURRENT APPLICATION ENCODING SCHEME, CURRENT SERVER, and CURRENT PACKAGESET are processed locally. All other special registers are processed at the server. That matters when you CONNECT to a remote location: CURRENT DATE is the remote server’s clock, not the requester’s TSO session clock.
“Session” here means the application process — the Db2 thread for your TSO session, CICS transaction, IMS region, RRSAF connection, or DDF connection. Register values last for that process until you SET them, CONNECT (for CURRENT SERVER), the connection ends, or (for some registers that were never explicitly set) a commit re-initializes them.
They are not a single global value for the Db2 subsystem, and they are not automatically shared across different connections from the same human. A COBOL batch job and a SPUFI session for the same TSO ID are different processes.
Plan for this in long-running programs that mix SET CURRENT SQLID with dynamic SQL and commit often: either SET PATH after changing SQLID, or SET PATH once at startup so commit does not surprise you.
You can use all special registers inside a stored procedure or user-defined function. You can SET only the ones that have SET statements. After the routine returns, Db2 restores every special register to the values from before the CALL. The caller never keeps a SET that happened inside the routine.
CREATE PROCEDURE / CREATE FUNCTION options control the starting values inside the routine:
Client-info registers are inherited from the invoking application and are not SET with SQL inside the routine. CURRENT DATE / TIME / TIMESTAMP are not inherited as a frozen snapshot for ordinary routines: each SQL statement in the routine takes a new clock reading — unless the routine runs under a trigger, in which case datetime registers can follow the triggering statement’s timestamp.
If a datetime special register is used in a function or procedure that sits in the scope of a trigger, Db2 uses the timestamp of the triggering SQL statement. That keeps BEFORE and AFTER trigger actions on the same logical clock as the INSERT or UPDATE that fired them.
Several registers exist mainly to steer dynamic SQL: CURRENT SCHEMA, CURRENT SQLID (for many privilege and ownership checks), CURRENT PATH, CURRENT QUERY ACCELERATION, CURRENT REFRESH AGE, CURRENT MAINTAINED TABLE TYPES FOR OPTIMIZATION. Static SQL uses bind options instead (QUALIFIER, PATH, QUERYACCELERATION, DYNAMICRULES, and so on). CURRENT PACKAGE PATH and CURRENT PACKAGESET are notable exceptions: they affect package resolution for both static and dynamic statements.
DYNAMICRULES on a package can also override how SET CURRENT SQLID behaves inside a stored procedure: if the package is not run-time behaviour, SET CURRENT SQLID may not change the authorization ID used for dynamic SQL in that package.
Besides SET in your program, shops often set registers from:
Precedence is usually ZPARM (lowest), then bind option if specified, then an explicit SET in the application (highest). Always check the register’s own page in the SQL Reference when you need the exact stack.
Imagine each program that talks to Db2 wears a backpack. Inside the backpack are labelled cards: “today’s date”, “my name”, “which toy box to look in first” (schema), and “which extra helpers to search” (path). When SQL says CURRENT DATE, Db2 peeks at the date card in that backpack — not a giant sign on the machine room wall that everyone shares. You can rewrite some cards with SET. You cannot rewrite the date card; the clock writes that one. If you hand the backpack to a helper procedure, the helper might copy your cards or start with a fresh set, but when the helper is done, your backpack looks exactly like it did before you called them.
1. What is a special register in Db2 for z/OS?
2. If CURRENT DATE and CURRENT TIMESTAMP appear in the same SQL statement, what happens?
3. Does ROLLBACK undo SET CURRENT SCHEMA?
4. After a stored procedure finishes, what happens to special registers it changed?
5. How do you read the value of CURRENT SQLID in interactive SQL?