问题
I found a number of discussions about this, and it seems mySQL simply doesn't allow the use of recursive triggers. Other discussions advise against trying to do this, but I'm fairly confident in the design of my trigger, so it doesn't run the risk of an infinite loop.
I guess I'm asking for confirmation on this limitation/design choice in mySQL, and any suggestions for an alternate approach to what I am trying to achieve.
---'PROBLEM'---
To sum up, I have a database that includes a contacts/users table, and a number of 'info' tables such as addresses/phones/emails. For the purposes of this question, I'll just focus on addresses. The address table has a contact_id col, to specify which contact it belongs to.
To quickly clarify, a contact can have none-to-many addresses attached to their account which is why I separated that information to an individual table.
When a user logs into their account, I do a query to get a list of addresses with their contact_id, and then allow them to edit it/delete it/add a new entry, etc.
I now want to specify a primary address for contacts, so when completing an order the drop down of their available addresses defaults to their primary.
I'm trying to set up a trigger on address update, so if the is_primary col is updated from 0/false to 1/true it also updates the previous primary address.
Essentially I only want 1 row per contact_id in the addresses table to be able to have is_primary set to 1/true.
---APPROACH---
I wrote the below trigger (I've tried with both before and after update)
CREATE TRIGGER tr_addresses_primary_bu
BEFORE UPDATE ON addresses
FOR EACH ROW
BEGIN
IF OLD.is_primary = 0 AND NEW.is_primary = 1 THEN
UPDATE addresses
SET addresses.is_primary = 0
WHERE addresses.is_primary = 1
AND addresses.contact_no = NEW.contact_no;
END IF;
END;
(Please ignore the multiple ';' delimiter situation for now)
I believe the trigger should be correct.
Before updating addresses
if is_primary changes from 0/false to 1/true (ie its made the primary)
change is_primary to 0/false of primary addresses (is_primary = 1/true) with the same contact_id
MySQL (accessed through phpmyadmin) lets me add the trigger but then throws an error when the trigger runs (when I update a rows is_primary from 0 to 1).
---WHY I THINK MY APPROACH SHOULD WORK---
I understand why an update table statement, inside a trigger called when updating that same table could cause problems. But I think this should be something left up to the designer.
This trigger cannot possibly hit an infinite loop, as the 'inside' update statement will always be updating OLD.is_primary = 1 to NEW.is_primary = 0, and the trigger update looks for OLD.is_primary = 0 to NEW.is_primary = 1.
It's a little frustrating to know that mySQL doesn't give me the control to do what I need, to save me from a possible issue that I've considered and addressed.
---QUESTIONS---
Does anyone know of how I could get this trigger to function in mySQL?
Does anyone see a problem with my trigger that I am perhaps overlooking?
Or does anyone have a suggestion to implement the condition I'm describing?
I know I could add a primary_addresses table, and alter that within a trigger. But I would really like to avoid adding a separate table. But I suppose if it will achieve the functionality I need, I should consider it.
来源:https://stackoverflow.com/questions/51543892/mysql-recursive-update-trigger