Db2 SQLCODE

SQLCODE -577: Routine not allowed to modify data

SQLCODE -577 (SQLSTATE 38002) means a user-defined function or stored procedure tried to change data or run DDL, but its definition, or the definition of a routine that called it, doesn't allow it. Only a routine running under MODIFIES SQL DATA may do that.

Other names for this code

Also written as SQL -577, SQLCODE=-577, SQLCODE = -577, db2 -577, sqlstate 38002, SQL0577N, attempted to modify data when the definition of the function or procedure did not specify this action.

What it means

Every function and stored procedure is defined with an SQL data access level. From most to least permissive, the levels are MODIFIES SQL DATA, READS SQL DATA, CONTAINS SQL and NO SQL. Db2 enforces the level while the routine runs. A routine that isn't allowed to modify data gets -577 when it issues an INSERT, UPDATE, DELETE, MERGE or a DDL statement. A NEXT VALUE expression for a sequence counts as modifying data too.

Nesting matters. When routines call each other, the most restrictive level anywhere in the chain applies. So a procedure defined MODIFIES SQL DATA still can't change data if it was called from a function or procedure defined READS SQL DATA. A routine defined READS SQL DATA, CONTAINS SQL or NO SQL can't even call one defined MODIFIES SQL DATA.

The message gives the object type and the name of the routine. SQLSTATE 38002 is the standard SQL code for this condition, and Db2 for LUW uses SQL0577N for it.

Common causes

  • Someone added an INSERT or UPDATE to a routine, such as audit logging, without changing its definition.
  • The routine uses NEXT VALUE FOR a sequence to build a key and is defined READS SQL DATA.
  • A procedure that changes data is called from a function or procedure defined with a weaker level.
  • The CREATE statement was copied from another routine that was defined READS SQL DATA.
  • The routine issues DDL while defined without MODIFIES SQL DATA.

How to find the problem

  1. Take the routine name from the message.
  2. Check its level with SELECT SCHEMA, NAME, ROUTINETYPE, SQL_DATA_ACCESS FROM SYSIBM.SYSROUTINES WHERE NAME = 'CALC_BONUS'. M means MODIFIES, R READS, C CONTAINS and N NO SQL.
  3. Run the same query for every caller above it in the chain. One of them may be the restrictive one.
  4. For an external routine, search its source for INSERT, UPDATE, DELETE, MERGE, DDL and NEXT VALUE.

How to fix it

  • Change the routine to MODIFIES SQL DATA with ALTER FUNCTION or ALTER PROCEDURE, or re-create it, and do the same for any caller that is more restrictive.
  • If the routine should only read, remove the statement that changes data and move it to the caller or a separate procedure.
  • Generate sequence values outside a read-only routine and pass them in.
  • Retest the whole call chain after the change, since the effective level comes from the most restrictive routine.

IBM documentation

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

Report a correction to WND Software.

Questions

My procedure is defined MODIFIES SQL DATA. Why does it still get -577?

Because something that called it is more restrictive. The lowest level in the whole call chain applies, so check the calling function or procedure.

Does NEXT VALUE FOR a sequence count as modifying data?

Yes. A routine that uses NEXT VALUE has to be defined MODIFIES SQL DATA.

What is the difference between -577 and -579?

-577 is about changing data. -579 is the same check for reading data, raised when a routine defined CONTAINS SQL or NO SQL tries to read a table.