SQLCODE -304: Value out of range for host variable
SQLCODE -304 (SQLSTATE 22003) means Db2 couldn't put a value into an output host variable because the value is outside the range that variable's data type can hold. The message gives both data types and the variable's position.
Other names for this code
Also written as SQL -304, SQLCODE=-304, SQLCODE = -304, db2 -304, sqlstate 22003, SQL0304N, not within the range of the host variable.
What it means
A FETCH, SELECT INTO, VALUES INTO, SET or CALL puts each result value into a host variable. The types can be compatible and the value can still not fit. A halfword holds up to 32,767. A fullword holds about 2.1 billion. A packed decimal field holds only as many digits as it was declared with. When a value is bigger than the target can hold, Db2 doesn't cut it down. It fails with -304.
The message names the value's data type, the host variable's data type and the host variable's position in the INTO list. That usually makes the cause plain, for example BIGINT going into INTEGER.
An indicator variable changes the outcome. If the host variable has one, Db2 can report the problem as the warning +304 instead, set the indicator to -2 and carry on with the rest of the row. Without an indicator, the statement fails and no data is returned. If it was a FETCH, the cursor stays open.
Common causes
- COUNT(*) or another count fetched into a halfword (PIC S9(4) COMP) field, which overflows once the count passes 32,767.
- A BIGINT column, or a value that grew past the INTEGER limit, fetched into a fullword field. IBM has seen this with large catalog statistics.
- A SUM or other calculation that returns more digits than the packed decimal host variable was declared with.
- A column altered to a larger type or precision while the program's DCLGEN still has the old size.
- A decimal value with more integer digits than the host variable allows, for example DECIMAL(15,2) into PIC S9(7)V99 COMP-3.
How to find the problem
- Read both data types and the position in the
DSNT408Imessage. Count along the INTO list to find the host variable. - Compare the column or expression type with the host variable declaration. Check the column in SYSIBM.SYSCOLUMNS and the program's DCLGEN.
- Find the row that failed and look at the actual value. It may be the first value large enough to overflow.
- For SUM and other calculations, work out the result type Db2 uses. It is usually wider than the column.
How to fix it
- Declare the host variable with a large enough type, such as a fullword or doubleword binary field, or a packed decimal field with more digits.
- Regenerate DCLGEN after the column changes, update the program, then precompile and bind again.
- If the value must be limited, convert or check it in the SQL, for example with a CASE expression, rather than letting the fetch fail.
- Add an indicator variable if the program should carry on and handle out-of-range values itself.
What it looks like
DSNT408I SQLCODE = -304, ERROR: A VALUE WITH DATA TYPE BIGINT CANNOT BE ASSIGNED TO A HOST
VARIABLE BECAUSE THE VALUE IS NOT WITHIN THE RANGE OF THE HOST VARIABLE IN POSITION 3
WITH DATA TYPE INTEGER
DSNT418I SQLSTATE = 22003 SQLSTATE RETURN CODEIBM documentation
IBM documentation: -304. Use the documentation for your installed release.
Related codes
Questions
Why did a COUNT start failing with -304?
The count passed what the host variable can hold. A halfword field tops out at 32,767, so a table that grows past that breaks the program.
What's the difference between -304 and +304?
+304 is a warning returned when the host variable has an indicator variable. Db2 sets the indicator to -2 and continues. Without an indicator you get the error -304.
Is it the same on Db2 for LUW?
Yes. SQL0304N means the value is not within the range of the host variable's data type, with SQLSTATE 22003.