What it means
A COBOL or PL/I field can't hold "no value". It always contains something. So when a column or expression in the SELECT list could be null, Db2 needs a second field, the indicator variable, to say whether the main field is valid. The indicator is a halfword, PIC S9(4) COMP in COBOL, written after the host variable in the INTO clause, as in :WS-BONUS :WS-BONUS-IND.
When a value is null and there is an indicator, Db2 sets the indicator to a negative number and puts no value in the host variable. When there is no indicator, Db2 has nowhere to report the null, so it fails the FETCH or SELECT INTO with -305. The message gives the output host variable's position, counted from 1 in the INTO clause.
A null can come from places other than a nullable column. Column functions, outer joins and CASE expressions can all produce one even when every column involved is NOT NULL.
Common causes
- A nullable column is fetched without an indicator. The column may have held values for years until a new process started leaving it empty.
- A column function such as SUM, MAX, MIN or AVG ran over no rows. It still returns one row, but the value is null, even if the column itself is NOT NULL.
- An outer join found no matching row on one side, so every column from that side comes back null.
- A CASE expression has no ELSE, and none of its WHEN conditions matched.
- A scalar subquery in the SELECT list found no row.
- A nullable column was added to an existing SELECT list without an indicator.
How to find the problem
- Read the position number in the message, then count the host variables in the INTO clause from left to right to find which one it is.
- Check the column's NULLS value in SYSIBM.SYSCOLUMNS. Y means the column can be null.
- If the item is a column function, a column from the outer side of a join or a CASE without ELSE, assume it can be null whatever the column definitions say.
- Rerun the query in SPUFI with the same values. SPUFI shows a null as dashes, so you can see which column it is.
How to fix it
- Add an indicator variable for every output column that can be null, and test it before using the host variable. A negative value means null.
- Or replace the null in SQL with COALESCE, for example
SELECT COALESCE(SUM(AMT), 0). Db2 for z/OS also accepts VALUE, which works the same way. - For a host structure, give an indicator array so every field in the structure has its own indicator.
- Let DCLGEN generate the indicator variables. Its indicator variables option builds an indicator array to match the table.
What it looks like
ACCTRPT - FETCH CSR-BAL FAILED, ACCT 7700412
DSNT408I SQLCODE = -305, ERROR: THE NULL VALUE CANNOT BE ASSIGNED TO OUTPUT HOST VARIABLE
NUMBER 4 BECAUSE NO INDICATOR VARIABLE IS SPECIFIED
DSNT418I SQLSTATE = 22002 SQLSTATE RETURN CODE