SQL types and language types are two views of the same bytes. DB2 for z/OS decides whether a column, a literal, and a host variable may be assigned or compared using compatibility, precedence, promotion, and casting rules. This page is the mechanics overview: how those rules work, then how COBOL, C, PL/I, REXX, ODBC, JDBC, and SQLJ map the common types—including graphic conversion, binary data, TIMESTAMP precision, time zones, and the CURRENT DATE / TIME / TIMESTAMP special registers.
Every value in SQL has a data type with attributes: length, precision, scale, CCSID, nullability, datetime precision, and (for distinct types) a source type. When two values meet—in assignment, comparison, concatenation, arithmetic, or a function call—Db2 applies a checklist:
Host variables add a second mapping: the precompiler or driver translates a COBOL PIC, a C type, or a java.sql.Types code into an SQL type. If that mapping is wrong, you get truncation, decimal-point disasters, or SQLCODE -301 / -312 style mismatches even when the SQL looks fine.
Compatible types may be assigned or compared (with conversion if needed). Incompatible types are errors unless you CAST to a type that is compatible with the other operand.
Concatenation requires compatible strings in the same grouping. You cannot CONCAT a binary string with a character string, including FOR BIT DATA character strings.
Within a family, types are ordered from best (same type) to worse (more general). Promotion means treating a value as a type later in that list. Promotion is used in function resolution, some distinct-type casts, and assigning user-defined types to built-in types.
| Starting type | Can promote toward |
|---|---|
| CHAR | VARCHAR, CLOB |
| VARCHAR | CLOB |
| GRAPHIC | VARGRAPHIC, DBCLOB |
| SMALLINT | INTEGER, BIGINT, decimal, real, double |
| INTEGER | BIGINT, decimal, real, double |
| DATE / TIME / TIMESTAMP | same datetime type only |
| BLOB / CLOB / DBCLOB | same LOB type only |
Examples: CHAR can be promoted to VARCHAR; INTEGER can be promoted toward BIGINT or decimal or float; CLOB cannot be promoted “down” to VARCHAR. DATE does not promote to TIMESTAMP automatically in the numeric-style list—datetime types stay in their own bucket unless you CAST. The best match in function resolution is always the same type before a promoted type.
CAST(expression AS type) (and cast functions such as INTEGER, VARCHAR, DATE) convert explicitly. Use CAST when:
12345SELECT CAST(HIREDATE AS VARCHAR(10)) AS HIRE_CHAR, CAST('2024-01-15' AS DATE) AS D, INTEGER('42') AS N FROM HR.EMPLOYEE FETCH FIRST 1 ROW ONLY;
Implicit casts still happen (fixed to varying string, some numeric widenings). Do not rely on them for distinct types or for character-to-datetime in portable SQL. Details live on the casting-and-data-conversion page; here the rule is: if the compiler complains, CAST is the first tool, not a random host-variable PIC change.
Assignment (INSERT, UPDATE, SET, SELECT INTO, FETCH) is stricter about length and precision than comparison. A VARCHAR(10) value assigned to CHAR(5) truncates (and may warn). A DECIMAL(9,2) assigned to SMALLINT must be a whole number in range or you get overflow. Null requires an indicator on the host side. Datetime assignment from a string uses the datetime string format rules, not “any PIC X.”
Host variable compatibility means the SQL type Db2 infers from the host declaration must be compatible with the column or parameter. Truncation examples IBM highlights: fetching CHAR(80) into PIC X(70) drops 10 characters; fetching DOUBLE into PIC S9(8) COMP drops the fraction. Match lengths on purpose.
Prefer DCLGEN so pictures match the catalog. Modern DCLGEN can emit COMP-5 for integers so TRUNC(OPT) in Enterprise COBOL is safe.
| SQL type | Typical COBOL |
|---|---|
| SMALLINT | PIC S9(4) COMP-5 |
| INTEGER | PIC S9(9) COMP-5 |
| BIGINT | PIC S9(18) COMP-5 |
| DECIMAL(p,s) | PIC S9(p-s)V9(s) COMP-3 |
| REAL / DOUBLE | COMP-1 / COMP-2 |
| CHAR(n) | PIC X(n) |
| VARCHAR(n) | 49-level length + PIC X(n) |
| DATE / TIME / TIMESTAMP | PIC X(10) / X(8) / X(26+) depending on precision |
| CLOB / BLOB / DBCLOB | SQL TYPE IS CLOB(n) / BLOB(n) / DBCLOB(n) |
| Locator | SQL TYPE IS CLOB-LOCATOR (etc.) |
1234501 HV-EMPNO PIC X(6). 01 HV-SALARY PIC S9(7)V9(2) COMP-3. 01 HV-SALARY-IND PIC S9(4) COMP-5. 01 HV-HIREDATE PIC X(10). 01 HV-RESUME USAGE IS SQL TYPE IS CLOB-LOCATOR.
In C (and C++) embedded SQL, short/int/long (and long long for BIGINT) map to the integer family; double to DOUBLE; decimal types often need SQL TYPE IS DECIMAL or packed structures; NUL-terminated char arrays map to CHAR/VARCHAR with length care (the NUL is not stored in Db2). LOBs use SQL TYPE IS CLOB(n) and locator forms. Graphic data uses wchar-oriented or SQL TYPE IS GRAPHIC declarations depending on the precompiler. Always include NUL terminator space in the C array that you do not count in the SQL length.
PL/I FIXED BIN(15) aligns with SMALLINT, FIXED BIN(31) with INTEGER, FIXED BIN(63) with BIGINT, FIXED DEC(p,s) with DECIMAL, FLOAT BIN with floating-point, CHAR(n) and CHAR(n) VAR with CHAR/VARCHAR, GRAPHIC with graphic types. LOB locators are DECLARE ... SQL TYPE IS CLOB_LOCATOR (underscores). PL/I VARYING strings carry a length prefix the precompiler understands—do not confuse them with COBOL 49-level groups.
REXX variables are strings from the language’s point of view. Db2 infers SQL types from how you pass data and from explicit typing functions in the REXX SQL interface. There is no PIC clause. Numeric-looking strings can be sent as DECIMAL or INTEGER depending on format. LOBs map toward strings. For production data movement, prefer COBOL/C/Java where types are explicit; use REXX for tooling and check SQLCODE after every statement.
ODBC applications bind with SQLBindParameter / SQLBindCol using C types (SQL_C_CHAR, SQL_C_LONG, SQL_C_TYPE_TIMESTAMP, SQL_C_BINARY, …) and SQL types (SQL_VARCHAR, SQL_INTEGER, SQL_TIMESTAMP, SQL_BLOB, …). The driver converts between them. Timestamp structs include fraction fields that must match TIMESTAMP(p). Wide-character C types pair with graphic/Unicode columns. Check the IBM ODBC type table for DECFLOAT and XML, which need driver-specific type codes.
JDBC and SQLJ share the Java-to-SQL table. Use the recommended first Java type on setXXX / getXXX and on SQLJ host expressions.
| SQL type | Java type | java.sql.Types |
|---|---|---|
| SMALLINT | short | Types.SMALLINT |
| INTEGER | int | Types.INTEGER |
| BIGINT | long | Types.BIGINT |
| DECIMAL / DECFLOAT | java.math.BigDecimal | Types.DECIMAL / DECFLOAT |
| CHAR / VARCHAR | String | Types.CHAR / VARCHAR |
| BINARY / VARBINARY | byte[] | Types.BINARY / VARBINARY |
| CLOB | java.sql.Clob | Types.CLOB |
| BLOB | java.sql.Blob | Types.BLOB |
| DATE / TIME / TIMESTAMP | java.sql.Date / Time / Timestamp | Types.DATE / TIME / TIMESTAMP |
| XML | java.sql.SQLXML | Types.SQLXML |
SQLJ uses the same Java types in :host expressions. Stored procedure Java methods must match CREATE PROCEDURE parameter types; if you use a non-default Java type on z/OS you may need a method signature in the EXTERNAL clause. DBCLOB often surfaces as Clob. ROWID uses java.sql.Types.ROWID. DECFLOAT commonly uses BigDecimal plus a DB2Types DECFLOAT code.
Graphic (DBCS / Unicode graphic) data is not CHAR. Conversion between SBCS, mixed, and graphic uses CCSID pairing. Host GRAPHIC variables (COBOL PIC G ... DISPLAY-1, PL/I GRAPHIC) must match the column’s encoding scheme. UX'...' literals are UTF-16 graphic constants. Implicit conversion can occur, but “looks like garbage in the terminal” is usually a CCSID or host-type mismatch, not a bad predicate. Do not store graphic data in PIC X and hope.
BINARY, VARBINARY, and BLOB are binary strings. Host mappings are SQL TYPE IS in COBOL and PL/I, byte[] or Blob in Java, SQL_C_BINARY in ODBC. Character FOR BIT DATA is a legacy overlap: it is still a character type for many SQL rules. New work should use true binary types and BX'...' literals. Concatenation and comparison stay inside the binary family.
TIMESTAMP(p) stores p fractional second digits (0 through 12). A host PIC X(26) matches the older TIMESTAMP(6) external form (19 characters of datetime plus a dot plus 6 digits). Higher precision needs a longer character host variable or a typed timestamp structure. JDBC java.sql.Timestamp nanos do not cover all 12 digits; know the driver’s rounding.
TIMESTAMP WITH TIME ZONE adds an offset. Assignment between WITH TIME ZONE and without it is a conversion, not a silent ignore of the zone. Session time zone special registers affect how some values are interpreted.
1234VALUES CURRENT DATE, CURRENT TIME, CURRENT TIMESTAMP, CURRENT TIMESTAMP WITH TIME ZONE;
All three are evaluated in a way that is consistent for the statement (you do not get a different DATE in the SELECT list and the WHERE clause of the same statement). Host variables that receive them must be assignment-compatible: PIC X(10) for DATE, PIC X(8) for TIME, and a timestamp-length string or SQL TYPE for TIMESTAMP. Java uses java.sql.Date, Time, and Timestamp respectively.
Imagine LEGO bricks that only snap to the same shape of brick. Numbers snap to numbers, letters snap to letters, pictures-of-clocks snap to clocks. Promotion is using a small brick in a hole that also fits a bigger brick of the same colour. CAST is melting a brick and recasting it as another shape when the rules allow. Host mappings are the instruction sheet that says “this COBOL box is the INTEGER brick.” If you put an INTEGER brick in a tiny COBOL box, extra studs snap off (truncation).
Compatibility is the set of rules that decide whether two types can be assigned, compared, concatenated, or passed to a function together. Related families (numbers, character strings, graphic strings, binary strings, datetime) have their own matrices. Distinct types are compatible mainly with themselves unless you CAST.
Use DCLGEN when you can. Typical mappings: SMALLINT to PIC S9(4) COMP-5, INTEGER to PIC S9(9) COMP-5, BIGINT to PIC S9(18) COMP-5, DECIMAL to PIC S9(p-s)V9(s) COMP-3, CHAR(n) to PIC X(n), VARCHAR to a 49-level length plus PIC X(n) group, DATE/TIME/TIMESTAMP to PIC X of the external length, LOBs and locators with SQL TYPE IS.
Promotion is an implicit widening along a precedence list (SMALLINT can be treated as INTEGER). Casting (CAST or a cast function) is an explicit conversion that can also change length, precision, or move between families when the cast is supported (string to DATE, for example).
JDBC uses java.sql.Types plus Java classes: short/int/long, BigDecimal, String, byte[], Date/Time/Timestamp, Clob, Blob, SQLXML. SQLJ host expressions use the same Java types. Prefer the first recommended Java type in IBM’s mapping tables for setXXX and getXXX calls.
TIMESTAMP(p) can store 0–12 fractional second digits. Host variables and JDBC Timestamp objects must be long enough or you truncate. TIMESTAMP WITH TIME ZONE adds offset information; CURRENT TIMESTAMP, CURRENT DATE, and CURRENT TIME are special registers whose types must match the columns or host variables you assign them to.
1. What is data type promotion in Db2?
2. A typical COBOL mapping for INTEGER is:
3. Which Java type is recommended for a VARCHAR column in JDBC?
4. Can CHAR be promoted to VARCHAR?
5. What does CURRENT TIMESTAMP return?