Db2 SQLCODE

SQLCODE -804: Error in the program's SQL input parameters

SQLCODE -804 (SQLSTATE 07002) means Db2 rejected the parameter list or the SQLDA that the program passed with an SQL statement, so the statement never ran. The two-digit reason code at the end of the message says which check failed.

Other names for this code

Also written as SQL -804, SQLCODE=-804, SQLCODE = -804, db2 -804, sqlstate 07002, SQL0804N, sqlcode -804 reason 11, db2 -804 reason 12.

What it means

In a precompiled program, every SQL statement turns into a call to Db2. The precompiler or the Db2 coprocessor builds a parameter list for that call in the program's own storage. Dynamic SQL that uses descriptors also passes an SQLDA, which the program fills in itself. Db2 checks both before it runs anything. When a field makes no sense, the statement fails with -804.

The reason code points at the field. These are the ones seen most in practice.

  • 01 and 02. OPEN or CLOSE was issued for a statement that isn't a cursor.
  • 06 and 07. The SQLDA format or its length is wrong.
  • 08 and 16. An input or output SQLTYPE isn't one Db2 knows.
  • 09 and 10. An input or output length is invalid.
  • 11. SQLDABC doesn't agree with SQLD.
  • 12 and 13. An input or output data pointer is invalid. In REXX, reason 12 often means a host variable or indicator variable was never given a value.
  • 14. SQLN asks for more entries than SQLDABC allows.
  • 17. The SQLDA describes a LOB, but the seventh byte of SQLDAID isn't set to '2' or higher, so Db2 assumes the extended SQLVARs weren't allocated.
  • 18. An ARRAY type was put in the SQLDA.

In static SQL the parameter list belongs to the precompiler, so -804 there usually means something overwrote it. In dynamic SQL it usually means the SQLDA was set up wrong.

Common causes

  • A dynamic SQL program filled in the SQLDA wrongly. Typical slips are an SQLTYPE value Db2 doesn't recognize, a zero length, or an SQLD larger than the number of SQLVAR entries the program allocated.
  • SQLDABC wasn't set to match the storage allocated. For a standard SQLDA it's 16 bytes of header plus 44 bytes for each SQLVAR.
  • A LOB column is described in the SQLDA, but the program didn't allocate the extended SQLVARs and set the seventh byte of SQLDAID (reason 17).
  • A table subscript running past its end, a bad group MOVE or a stray pointer overwrote the precompiler's call parameter list.
  • The program declares its own variables with names starting with SQL, which can clash with names the precompiler generates.
  • Someone edited the precompiler output by hand.
  • A REXX program used a host variable or indicator variable that was never assigned (reason 12).

How to find the problem

  1. Read the reason code in the DSNT408I message, or in SQLERRMC if the program formats its own messages. It narrows the problem to one field.
  2. For dynamic SQL, display the SQLDA just before the failing EXECUTE, OPEN or FETCH. Check SQLN, SQLD and SQLDABC, then each SQLTYPE and SQLLEN, against what DESCRIBE returned.
  3. For static SQL, find the failing statement in the precompiler listing and look at the code that runs before it. A loop that fills a table without a range check is the usual suspect.
  4. If a different statement fails from one run to the next, suspect a storage overlay rather than the statement itself. A dump or a debugger watch on the SQL parameter area shows what writes to it.

How to fix it

  • Set SQLN to the number of SQLVARs you allocated and SQLDABC to the matching size before you DESCRIBE or use the SQLDA.
  • Use SQLTYPE values from the Db2 SQL reference. An odd SQLTYPE tells Db2 an indicator variable is present, so point SQLIND at one.
  • For LOB columns, allocate the doubled set of SQLVARs and set the seventh byte of SQLDAID to '2' or higher.
  • Fix any overlay at its source. Add range checks, compile with SSRANGE in test and rename program variables that start with SQL.
  • Precompile again instead of patching generated code. In REXX, assign every host variable before the EXECSQL that uses it.

What it looks like

DSNT408I SQLCODE = -804, ERROR:  AN ERROR WAS FOUND IN THE APPLICATION PROGRAM INPUT
         PARAMETERS FOR THE SQL STATEMENT, REASON 11
DSNT418I SQLSTATE   = 07002 SQLSTATE RETURN CODE

IBM documentation

IBM documentation: -804. Use the documentation for your installed release.

Report a correction to WND Software.

Questions

Is -804 a Db2 problem?

Very rarely. Db2 is reporting that the parameter list or SQLDA it was handed is wrong. The fix is nearly always in the program.

Do the reason codes match SQL0804N on Db2 for LUW?

No. Db2 for LUW uses the same SQLCODE and SQLSTATE 07002, but its reason codes are its own list. A reason number from one platform doesn't mean the same thing on the other.

Can a CICS program get -804?

Yes. The checks are the same under every attachment. In CICS the usual cause is a storage overlay in the program's working storage.