Db2 SQLCODE

SQLCODE -206: Column name not valid

SQLCODE -206 (SQLSTATE 42703) means the SQL refers to a column name Db2 can't match to any table in the statement. It's usually a typo, a column that doesn't exist in this copy of the table, or a string written in double quotes.

Also written as SQL -206, SQLCODE=-206, SQLCODE = -206, db2 -206, sqlstate 42703, SQL0206N, is not valid in the context where it is used.

What it means

When Db2 binds or prepares a statement, it matches every column name against the tables and views in the FROM clause, or against the target table of an INSERT, UPDATE or DELETE. If a name doesn't belong to any of them, or belongs to a table the statement can't see at that point, Db2 rejects the statement with -206 and puts the name in SQLERRMC.

Static SQL usually hits this at BIND time. The bind fails and the program never gets a new package. If the package was bound with VALIDATE(RUN), the check is repeated each time the statement runs, and that's when the program sees -206. Dynamic SQL gets it on PREPARE or EXECUTE IMMEDIATE.

The program compiles cleanly either way. The COBOL compiler never looks at the SQL, and the precompiler doesn't read the Db2 catalog, so BIND is the first point where a column is checked against the real table.

Common causes

  • The column name is misspelled, or it's an old name from before the table was changed.
  • The column exists in the test table but not in production yet, because the ALTER TABLE ADD COLUMN hasn't been run there.
  • A string was written in double quotes, as in WHERE STATUS = "A". In SQL, double quotes mark a name, so Db2 looks for a column called A. Strings need single quotes unless the program was precompiled with the QUOTESQL option.
  • A host variable is missing its colon, so Db2 tries to read the program field name as a column.
  • A correlation name is wrong or out of scope, such as a column qualified with a name that's defined only inside a subquery, or with the other table's correlation name.

How to find the problem

  1. Read the name in the DSNT408I message, the DSNX200I bind message or SQLERRMC. That is the exact name Db2 couldn't match.
  2. List the table's columns in the subsystem where the error happened, not only in test, with SELECT NAME FROM SYSIBM.SYSCOLUMNS WHERE TBCREATOR = 'PAYPROD' AND TBNAME = 'EMP_HIST'.
  3. If the name looks like data, such as a single letter or a status code, search the statement for double quotes.
  4. If the name looks like a program field, such as one starting WS-, look for a host variable that lost its colon.
  5. For a bind failure, the STATEMENT number in the DSNX200I message points to the statement in the precompile listing.

How to fix it

  • Correct the column name in the program, then precompile, compile and bind again.
  • If the column is new, run the ALTER TABLE in this environment before the program moves here. Table changes and program changes need to be promoted together.
  • Put strings in single quotes, or check the APOSTSQL and QUOTESQL precompiler options if your shop uses double quotes on purpose.
  • Add the missing colon to the host variable.
  • If you fixed the table rather than the program, rebind the package. A package bound with VALIDATE(RUN) that still names a missing column fails every time that statement runs.

What it looks like

DSNX200I -DB2P BIND SQL ERROR
           USING PAYOWN AUTHORITY
           PLAN=(NOT APPLICABLE)
           DBRM=PAYUPD1
           STATEMENT=412
           SQLCODE=-206
           SQLSTATE=42703
           TOKENS=HIRE_DT
DSNT233I -DB2P UNSUCCESSFUL BIND FOR
           PACKAGE = DB2P.PAYCOLL.PAYUPD1.()

Questions

Why did the BIND fail with -206 when the program compiled fine?

The compiler and precompiler don't check column names against the catalog. BIND is the first step that compares the SQL with the real table, so that's where a bad column shows up.

Is -206 the same as -204?

No. -204 means the table or other object is missing. -206 means the table was found but a column name in the statement doesn't fit.

Why does a one-letter column name appear in the error?

A string like "Y" in double quotes is read as a column name. Change it to 'Y' with single quotes.