Beginner to mysql trigger, I do some searches but can't reach my objective, I simply want to restrain an update query on a specific table to one row or cancel it. For multiple raisons I have to do that on the mysql server side.
Here is my trigger :
DELIMITER //
DROP TRIGGER IF EXISTS prevent_multiple_update //
CREATE TRIGGER prevent_multiple_update
BEFORE UPDATE ON `my_table`
FOR EACH ROW
BEGIN
IF( @rows_being_updated IS NULL ) THEN
SET @rows_being_updated = 1;
ELSE
SET @rows_being_updated = NULL;
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Cannot update more than one line per time';
END IF;
END //
DELIMITER ;
It works as expected for the first query, but only for the first one.
If I try :
UPDATE `my_table` SET company=1 WHERE id=1;
It work, query is executed
If I try :
UPDATE `my_table` SET company=1 WHERE id=1 OR id=2;
It work, query is NOT executed
But, if i try :
UPDATE `my_table` SET company=1 WHERE id=1;
UPDATE `my_table` SET company=2 WHERE id=2;
The first one is executed but the second one trig the trigger and is not executed, it's like var @rows_being_updated is not set to null.
Any idea?
Thank you.
CREATE TRIGGER prevent_multiple_update
BEFORE UPDATE ON test
FOR EACH ROW
BEGIN
IF @update_timestamp = NOW(6) THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Cannot update more than one line per time';
ELSE
SET @update_timestamp = NOW(6);
END IF;
END
How does this works?
The function NOW(6)
returns the datetime of the whole UPDATE query execution start (rather than SYSDATE()
) with the microsecond accuracy. It is impossible that two consecutive queries starts within a microsecond. So when the query updates only one row then the value returned by this function differs from one which was set during previous UPDATE (or it is NULL if this is the most first UPDATE within the connection). When the query tries to update more than one row then the function returns the same value for each its call within the query, the trigger detects this on the 2nd row updation and breaks the query.