MySQL Bug #11472 confirms that when rows of a tableB
are updated/deleted indirectly as a result of a FK constraint (relating tableA
), triggers on tableB
are not executed.
How can I workaround this bug? I found a messy workaround, but would like to hear the SO communities suggestions as well.
In this example
joins
has a FK tousers
and alsocars
. In this scenario, when a user is deleted, both the join and the car ought be deleted as well. To delete the car a trigger is created onjoins
to simulate the cascade.
CREATE TABLE `users` (
`id` varchar(10) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE `cars` (
`id` varchar(10) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE `joins` (
`user_id` varchar(10) NOT NULL,
`car_id` varchar(10) NOT NULL,
PRIMARY KEY (`user_id`,`car_id`),
FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
FOREIGN KEY (`car_id`) REFERENCES `cars` (`id`)
) ENGINE=InnoDB;
CREATE TRIGGER `on_delete_cascade_car`
AFTER DELETE ON `joins`
FOR EACH ROW
DELETE FROM `cars` WHERE `id` = OLD.`car_id`;
INSERT INTO users (`id`) VALUES ('Alice'), ('Bob');
INSERT INTO cars (`id`) VALUES ('Audi'), ('BMW');
INSERT INTO joins (`user_id`, `car_id`) VALUES ('Alice','Audi'), ('Bob','BMW');
-- delete a user (to show failed cascade) and a join (to show working trigger)
DELETE FROM users WHERE id = 'Alice';
DELETE FROM joins WHERE user_id = 'Bob';
-- shows cascade and direct delete worked
SELECT * FROM joins;
-- shows direct delete of Alice worked
SELECT * FROM users;
-- trigger deleted BMW when Bob|BMW join was directly deleted, but not Audi following cascaded delete
SELECT * FROM cars;