Two foreign keys reference one table - ON UPDATE SET NULL doesn't work

Wojciech Kulik picture Wojciech Kulik · Jan 27, 2013 · Viewed 11.1k times · Source

I've got two foreign keys in a table. Let's assume that table is called News and has foreign keys updatedById and createdById, both of which point to userId in table Users.

Now I want to set to NULL foreign keys when user is deleted, but when I try to set ON DELETE SET NULL in that relationships I get:

Introducing FOREIGN KEY constraint 'FK_News_Users' on table 'News' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.

I don't understand why both foreign keys can't set to null?

Answer

peterm picture peterm · Jan 28, 2013

Multiple Cascading Actions

The series of cascading referential actions triggered by a single DELETE or UPDATE must form a tree that contains no circular references. No table can appear more than one time in the list of all cascading referential actions that result from the DELETE or UPDATE. Also, the tree of cascading referential actions must not have more than one path to any specified table. Any branch of the tree is ended when it encounters a table for which NO ACTION has been specified or is the default.

Possibly in situations like this you might want to consider to implement functionality to delete user logically rather then physically (e.g. by introducing a flag field Active or Deleted in Users table). That way all relationships stay intact and can be analyzed retrospectively.

But if you still need to implement ON DELETE SET NULL for both FK's you can use a FOR DELETE trigger on User table like this:

CREATE TRIGGER Users_News_Delete_Trigger 
ON Users FOR DELETE
AS BEGIN
    UPDATE News SET createdById = NULL 
     WHERE createdById = DELETED.id;
    UPDATE News SET updatedById = NULL 
     WHERE updatedById = DELETED.id;
END