Some columns are secrets. Some are only fingerprints. DB2 for z/OS gives you one-way HASH functions, two-way encryption (ENCRYPT_DATAKEY with AES-256 key labels, and the deprecated ENCRYPT_TDES password functions plus GETHINT), and GENERATE_UNIQUE for time-based unique tokens. This page sticks to z/OS names from the SQL Reference and maps the checklist names HASH4 / HASH8 / HASH16 and ENCRYPT_DATA / DECRYPT_DATA onto what actually exists on the mainframe.
HASH applies a cryptographic hash algorithm to an input and returns binary bytes. Schema is SYSIBM. Named twins HASH_MD5, HASH_SHA1, HASH_SHA256, and HASH_CRC32 exist so ports and new SQL can say the algorithm in the function name.
12345HASH(expression [, algorithm]) HASH_MD5(expression) HASH_SHA1(expression) HASH_SHA256(expression) HASH_CRC32(expression)
| HASH second argument | Algorithm | Result |
|---|---|---|
| 0 (default) | MD5 / HASH_MD5 | VARBINARY(16) — 128-bit; not for new secrets |
| 1 | SHA-1 / HASH_SHA1 | VARBINARY(20) — 160-bit; not for new secrets |
| 2 | SHA-256 / HASH_SHA256 | VARBINARY(32) — 256-bit; preferred of this set |
| HASH_CRC32 | CRC32 checksum | Integrity / lookup checksum, not a password hash |
1234SELECT HASH(LASTNAME, 2) AS SHA256, HASH_SHA256(LASTNAME) AS SHA256_NAMED FROM DSN8C10.EMP WHERE EMPNO = '000010';
Null input yields a null hash. Hashes are for integrity checks, change detection, and (with care) fingerprints. They are not encryption. MD5 and SHA-1 are broken for collision resistance; do not use them for new security designs. SHA-256 is the least-wrong choice in this built-in set. Real password storage belongs in an application library with a slow salted hasher (bcrypt/argon2), not a single SQL HASH call.
Training outlines and Db2 LUW manuals list HASH4, HASH8, and HASH16 as fast checksum lookup functions (INTEGER / BIGINT / 128-bit), with Adler, CRC32, or Jenkins algorithms. The Db2 for z/OS SQL Reference documents HASH and HASH_algorithm instead. On z/OS, use HASH_CRC32 when you want a CRC-style checksum, and HASH / HASH_SHA256 when you want a cryptographic digest. Do not paste LUW HASH4(..., 0) examples into a z/OS package without verifying the name on your function level.
| Name | Typical LUW meaning |
|---|---|
| HASH4 | LUW: 32-bit INTEGER checksum (Adler default, or CRC32) |
| HASH8 | LUW: 64-bit BIGINT checksum (Jenkins); endian-sensitive |
| HASH16 | LUW: 128-bit binary checksum family for lookups |
These are the modern column-encryption functions (Db2 12 function level 505 and later). The checklist names ENCRYPT_DATA / DECRYPT_DATA refer to this family on z/OS.
1ENCRYPT_DATAKEY(expression, key-label [, 'AES256D' | 'AES256R'])
Decrypt with a typed function that matches what you encrypted:
Encrypting INTEGER and decrypting with DECRYPT_DATAKEY_VARCHAR fails (SQLCODE −171). There is no CHAR decrypt form — strings come back varying-length. Ciphertext is longer than cleartext; size the VARBINARY/BLOB column accordingly.
ENCRYPT_TDES (synonym ENCRYPT) applies Triple DES with a password. IBM marks it deprecated: the algorithms are not considered quantum-safe. Prefer ENCRYPT_DATAKEY.
12345ENCRYPT_TDES(string-expression [, password-string [, hint-string]]) DECRYPT_CHAR(encrypted, password) DECRYPT_BIT(encrypted, password) DECRYPT_DB(encrypted, password) GETHINT(encrypted-data)
Never hard-code production passwords in SQL text, host variables logged in traces, or tables. That design is exactly why key labels replaced password arguments.
These functions return a value unique compared with any other execution of the same function. Empty parentheses are required. They are not deterministic. The result cannot be null.
The value embeds UTC time and, in a sysplex, the member that processed the function. TIMESTAMP(unique-id) recovers that timestamp. Unlike CURRENT TIMESTAMP, each row of a multiple-row INSERT, INSERT with fullselect, or MERGE insert gets a distinct value.
12345678910CREATE TABLE EMP_UPDATE ( UNIQUE_ID VARCHAR(13) FOR BIT DATA, EMPNO CHAR(6), TEXT VARCHAR(1000) ); INSERT INTO EMP_UPDATE VALUES (GENERATE_UNIQUE(), '000020', 'Update entry 1...'); SELECT TIMESTAMP(UNIQUE_ID), EMPNO, TEXT FROM EMP_UPDATE;
A BEFORE INSERT trigger can force the column:
12345CREATE TRIGGER EMP_UPDATE_UNIQUE NO CASCADE BEFORE INSERT ON EMP_UPDATE REFERENCING NEW AS NEW_UPD FOR EACH ROW MODE DB2SQL SET NEW_UPD.UNIQUE_ID = GENERATE_UNIQUE();
A hash is a blender: you pour in a secret recipe and get a smoothie colour. You can check later whether a new recipe blends to the same colour, but you cannot un-blend the smoothie back into tomatoes. Encryption is a locked lunchbox: ENCRYPT_DATAKEY puts the sandwich in and tags the box with a label of which school key opens it. Only kids RACF says may use that key can open it. The old ENCRYPT_TDES lunchbox used a password written on a sticky note — IBM says stop doing that. GENERATE_UNIQUE is a ticket machine that never gives two people the same number, even when a whole crowd presses the button at once.
1. HASH(expr, 2) on Db2 for z/OS applies which algorithm?
2. Why is ENCRYPT_DATAKEY preferred over ENCRYPT_TDES?
3. What does GETHINT return?
4. GENERATE_UNIQUE() returns:
5. Are HASH4, HASH8, and HASH16 built-in on Db2 for z/OS the same way as on LUW?