Db2 SQLCODE

SQLCODE -532: Delete restricted by a foreign key

SQLCODE -532 (SQLSTATE 23504) means a DELETE tried to remove a parent row that still has dependent rows, and the foreign key's delete rule is RESTRICT or NO ACTION.

Also written as SQL -532, SQLCODE=-532, SQLCODE = -532, db2 -532, sqlstate 23504, SQL0532N, restricts the deletion of row.

What it means

Every foreign key has a delete rule that says what happens to child rows when their parent is deleted. CASCADE deletes the children too. SET NULL sets their foreign key to null. RESTRICT and NO ACTION refuse the delete while any child row still points at the parent.

Under RESTRICT or NO ACTION, deleting a parent that has children fails with -532. SQLERRMC holds the constraint name and the RID of the row that couldn't be deleted. The whole statement is undone, so even a DELETE meant for thousands of rows removes none of them.

The rule can bite one level down. Say deleting a customer cascades to its orders, but order lines point to orders with RESTRICT. Then deleting the customer fails with -532, and the message names the order-line constraint, not anything on the customer table.

Common causes

  • A program or user deleted a parent row, such as an order header, without deleting its child rows first.
  • A purge job deletes in the wrong order, parents before children.
  • A CASCADE from a higher table reached a relationship further down with RESTRICT or NO ACTION.
  • Another process added child rows after the purge job picked which parents to remove.
  • The DBA added a new foreign key, and an older delete program doesn't know about the new child table.

How to find the problem

  1. Take the constraint name from the DSNT408I message or SQLERRMC.
  2. Look it up in SYSIBM.SYSRELS. TBNAME is the child table, REFTBNAME the parent and DELETERULE the rule (A for NO ACTION, C for CASCADE, N for SET NULL, R for RESTRICT).
  3. List the child rows for the parent's key, using the columns in SYSIBM.SYSFOREIGNKEYS for that constraint.
  4. If the constraint isn't on the table your program deletes from, follow the CASCADE rules down from your table until you reach it.

How to fix it

  • Delete the child rows first, then the parent, in the same unit of work.
  • In purge jobs, work up from the bottom of the table hierarchy.
  • If the business wants children removed with the parent, ask the DBA to change the delete rule to CASCADE. That means dropping and adding the foreign key again, which needs planning on large tables.
  • If the parent should stay, have the program skip it, or mark it inactive instead of deleting it.

What it looks like

ORDPURG - DELETE ORDER_HDR FAILED, ORDER 00733018
DSNT408I SQLCODE = -532, ERROR:  THE RELATIONSHIP FKLINORD RESTRICTS THE DELETION OF ROW
         WITH RID X'0000041A07'
DSNT418I SQLSTATE   = 23504 SQLSTATE RETURN CODE

Questions

What's the difference between RESTRICT and NO ACTION?

Both stop the delete, and most of the time they behave the same. Db2 checks RESTRICT before any other referential actions in the statement and NO ACTION after them, which only matters when one delete sets off several cascades.

Why does -532 name a table I didn't delete from?

Your delete cascaded to a child table, and that table has its own children under a RESTRICT or NO ACTION rule. The constraint in the message is the one that stopped it.

Does updating a parent key give -532?

No. Changing a parent key that still has children gives -531.