SQLCODE -401: Operands not comparable
SQLCODE -401 (SQLSTATE 42818) means the two operands of a comparison or an arithmetic operation have data types that Db2 can't compare or combine, such as a date and a number. Make both sides the same kind of data, usually with an explicit conversion.
Other names for this code
Also written as SQL -401, SQLCODE=-401, SQLCODE = -401, db2 -401, sqlstate 42818, SQL0401N, db2 operands not comparable, SQL0401.
What it means
Db2 can compare numbers with numbers and strings with strings. It can compare dates, times and timestamps with values of the same type, or with strings that hold a valid date or time. Mixing other types fails with -401 when the statement is bound or prepared, before any rows are read.
Db2 10 for z/OS changed this for strings and numbers. From Db2 10 new-function mode, comparing a character string with a number makes Db2 cast the string to DECFLOAT(34), so WHERE CHAR_ no longer fails with -401. If a string holds something that isn't a number, you get -420 at run time instead. Programs that hit -401 for this reason on older releases may behave differently today.
The Db2 for z/OS message doesn't name the operator or the column. Db2 for LUW's SQL0401N does name the operator, which helps when the same SQL runs on both.
Common causes
- A date, time or timestamp column is compared with a number, for example
WHERE ORDER_or with a numeric host variable holding YYYYMMDD.DATE = 20261018 - A column with a distinct (user-defined) type is compared with a value of its source type without a cast. Distinct types are strongly typed.
- A binary string (BINARY or VARBINARY) is compared with a number, or in many cases with a character string.
- On releases before Db2 10, or before new-function mode, a character column was compared with a number.
- A comparison inside a CASE WHEN, an IN list or a BETWEEN mixes types, so one pair of operands doesn't match even though the others do.
- A column defined with a field procedure is compared with, or used in arithmetic with, a column that doesn't use the same field procedure.
How to find the problem
- List every comparison and arithmetic operation in the statement, including those in ON clauses, subqueries and CASE expressions.
- Look up each column's type in SYSIBM.SYSCOLUMNS (COLTYPE, LENGTH, SCALE) and each host variable's declaration in the program.
- For distinct types, check SYSIBM.
SYSDATATYPES for the source type. - If the statement reads a view and the SQL itself looks right, check the data types in the view definition.
- If the statement is long, remove predicates one at a time in SPUFI or another query tool until the error stops.
How to fix it
- Compare like with like. For dates, use a date string such as
'2026-10-18'or a function such asDATE(...). - Convert explicitly with CAST, CHAR, DECIMAL, DATE or TIMESTAMP_
FORMAT, so the result doesn't depend on implicit rules. - Declare host variables with the same type as the column. DCLGEN output is the safest source.
- Cast distinct types with the cast function Db2 created for them, or cast the other side to the distinct type.
IBM documentation
IBM documentation: -401. Use the documentation for your installed release.
Related codes
Questions
Why did my program fail with -401 before and now gets -420?
Db2 10 started casting strings to numbers when they're compared. The comparison is now allowed, but a string that isn't a valid number fails at run time with -420.
Can I compare a DATE column with a string?
Yes, if the string holds a valid date in a format Db2 accepts. A badly formed string gives -180, not -401.
Is SQL0401N on Db2 for LUW the same?
Yes. It has the same SQLSTATE, 42818, and its message names the operator. LUW also casts strings and numbers implicitly from version 9.7.