Db2 SQLCODE

SQLCODE -518: EXECUTE names an invalid prepared statement

SQLCODE -518 (SQLSTATE 07003) means an EXECUTE statement named a statement that isn't a valid prepared statement. It was never prepared, was discarded by a COMMIT or ROLLBACK, is a SELECT, or is a DDL statement that has already run once.

Other names for this code

Also written as SQL -518, SQLCODE=-518, SQLCODE = -518, db2 -518, sqlstate 07003, SQL0518N, execute statement does not identify a valid prepared statement.

What it means

EXECUTE runs a statement that the program prepared earlier with PREPARE. It is for statements that don't return rows, such as INSERT, UPDATE, DELETE, MERGE or DDL. Db2 checks the statement name when EXECUTE runs. If the name doesn't hold a statement it can execute, it returns -518 and does nothing.

There are several ways to get there. The statement may never have been prepared, or its PREPARE failed. A COMMIT or ROLLBACK may have destroyed it. The prepared statement may be a SELECT or an ASSOCIATE LOCATORS statement, and neither can be run with EXECUTE. A SELECT has to go through a cursor. EXECUTE IMMEDIATE can't run a SELECT either.

DDL has one more rule. Once a prepared CREATE, ALTER, DROP or other data definition statement has run, its prepared form can't be run again. The program has to prepare it again first.

Common causes

  • The PREPARE failed, often with -104 or -204, and the program called EXECUTE anyway.
  • A batch program prepares its statements once at the start, then commits every few hundred rows. The first EXECUTE after the first commit fails.
  • The SQL text built at run time turned out to be a SELECT, so it needed a cursor rather than EXECUTE.
  • A prepared DDL statement is executed a second time, for example in a loop that creates several objects from one prepared statement.
  • PREPARE and EXECUTE are in different programs with different packages.
  • On Db2 for LUW, the package was rebound while the application was connected, which invalidates its prepared statements.

How to find the problem

  1. Check the SQLCODE from the PREPARE of the same statement name.
  2. Log the SQL text the program passed to PREPARE. That shows at once whether it was a SELECT.
  3. Find the commit points. If -518 appears on the first EXECUTE after a COMMIT, the commit is the cause.
  4. Check how the package was bound with SELECT COLLID, NAME, KEEPDYNAMIC, RELEASE FROM SYSIBM.SYSPACKAGE WHERE NAME = 'ORDUPD01'.

How to fix it

  • Prepare the statement before every EXECUTE that follows a COMMIT or ROLLBACK, or bind the package with KEEPDYNAMIC(YES) so prepared statements survive commits.
  • If the prepared statement refers to a declared temporary table and must survive a COMMIT, IBM's advice is to bind with RELEASE(DEALLOCATE).
  • Run SELECT statements through a cursor (DECLARE, OPEN, FETCH, CLOSE), never EXECUTE.
  • Prepare DDL again each time it runs, or use EXECUTE IMMEDIATE for one-off DDL.
  • Check SQLCODE after every PREPARE so the real error surfaces.

What it looks like

ORDUPD01 - EXECUTE UPDSTMT FAILED AFTER COMMIT
DSNT408I SQLCODE = -518, ERROR:  THE EXECUTE STATEMENT DOES NOT IDENTIFY A VALID PREPARED STATEMENT
DSNT418I SQLSTATE   = 07003 SQLSTATE RETURN CODE

IBM documentation

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

Report a correction to WND Software.

Questions

Why does it only fail after the first commit?

A COMMIT destroys prepared statements unless the package was bound with KEEPDYNAMIC(YES). The first EXECUTE after the commit finds nothing prepared.

Is -518 the same on Db2 for LUW?

Yes. Db2 for LUW reports SQL0518N with SQLSTATE 07003. Its causes also include a SELECT or VALUES statement, and a rebind of the package while the application runs.

Can I EXECUTE a prepared SELECT?

No. A SELECT returns rows, so it has to be run through a cursor with OPEN and FETCH.