Two triggers and I am getting an error when updating table - mysql

I got the two following triggers, each one worked alone, but together they don't.
How can I make them to work together? They update different fields in table.
trigger 1:
create trigger wys_sk_u after update on `things`
for each row
begin
UPDATE `current` s
INNER JOIN things u ON s.id_thing = u.id_thing
INNER JOIN dude_base b ON b.id= s.id
SET s.`curr_cash` = u.cash1 * b.cash2/ 100;
end;
$$
trigger 2:
create trigger suma_u after update on `current`
for each row
begin
UPDATE `current`
SET `mysum` = `curr_cash` + `mysum`;
end;
$$
First one should update when cash1 or cash2 updates, and change value of curr_cash.
Second should update when curr_cash updates, and change mysum.
I got following error when I edit table things:
#1442 - Can't update table 'current' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
#edit
added new answear to the question.
What if I want to do something like this:
CREATE TRIGGER total BEFORE UPDATE ON `current` FOR EACH ROW
BEGIN
if new.`new_pay_date` <> old.`new_pay_date`
SET new.`total_cash` = new.`curr_cash` + new.`total_cash`;
end if;
END;
$$
Error:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SET new.`total_cash` = new.`curr_cash` + new.`total_cash`; end if;' at line 4
This was working without
if new.`new_pay_date` <> old.`new_pay_date`
end if;
But I need to check this, and only update with date change.
current table:
curr_cash
new_pay_date
id_person
id_thing
total_cash
Anyone can help me with this one?

The problem is in the second trigger. Try to use BEFORE UPDATE trigger to change field value using SET statement -
CREATE TRIGGER suma_u BEFORE UPDATE ON `current` FOR EACH ROW
BEGIN
SET new.`mysum` = new.`curr_cash` + new.`mysum`;
END;

It is not possible to update a table for for which the trigger is created in the trigger. There is locking mechanism on MySQL so that you can't update the row of the same table triggered the trigger, it can cause recursive call to the trigger and infinite loop.

Related

Update Trigger on same table MySQL 5.6

I have a table 'foods' with columns 'featured', 'restaurant_id', 'retaurant_stock'.
How can I update column 'restaurant_stock' using trigger or any other solution available on mySQL version 5.6 after update of column 'featured' on the same table on a condition?
Calculated columns are not available on mySQL version 5.6.
Here's my trigger:
CREATE TRIGGER update_restaurant_stock BEFORE UPDATE ON foods
OR EACH ROW
BEGIN
IF NEW.featured = 1 THEN
UPDATE `foods` SET NEW.restaurant_stock = (NEW.restaurant_id);
ELSE
UPDATE `foods` SET NEW.restaurant_stock = 0;
END IF;
END
Now when I update column 'featured' I get the following error message:
#1442 - Can't update table 'foods' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
Thanks for you help!
You can't update the current row that way, you can use set to change the new values
DELIMITER $$
CREATE TRIGGER update_restaurant_stock BEFORE UPDATE ON foods
OR EACH ROW
BEGIN
IF NEW.featured = 1 THEN
SET NEW.restaurant_stock = (NEW.restaurant_id);
ELSE
SET NEW.restaurant_stock = 0;
END IF;
END$$
DELIMITER ;
CREATE TRIGGER tr_bu_foods
BEFORE UPDATE
ON foods
FOR EACH ROW
-- update restaurant_stock
SET NEW.restaurant_stock = NEW.restaurant_id * (NEW.featured = 1);

trigger after update to delete row on condition

i want to create trigger after update to delete row on specific condition
i did find similar question here but the code won't work with me.
This is what i try to do :
DELIMITER $$
CREATE TRIGGER delete_rejected_friendship
AFTER UPDATE
ON friendship FOR EACH ROW
BEGIN
IF Update(RequestState)
BEGIN
DELETE FROM friendship WHERE RequestState = 'reject'
END
END
END$$
DELIMITER ;
This is the error which appears:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'Update(RequestState)
Begin
DELETE FROM friendship WHERE Reque' at line 9`
so i have friendship table that have three columns userID , friendID and RequestState. this table represent friendship relationship and friendship request state. if RequestState= accept then they are friends and if RequestState = reject the row should be deleted.
Edit :
if update(requeststate) for if the column = requeststate updated (changed from 'waiting' state to either 'accept' or 'reject' state) then the other condition in delete statement (WHERE RequestState = 'reject') to specify only change to 'reject' state
I think, You are using Update(RequestState) condition like PostgreSQL, in MySQL or MariaDB could be like that:
DELIMITER $$
CREATE TRIGGER delete_rejected_friendship
AFTER UPDATE
ON friendship FOR EACH ROW
BEGIN
IF NEW.RequestState <> OLD.RequestState THEN
BEGIN
DELETE FROM friendship WHERE RequestState = 'reject';
END;
END IF;
END;
$$
DELIMITER ;

Trigger before update causes error #1442

Hello I have a problem with this trigger:
CREATE TRIGGER sprLog AFTER UPDATE ON Users FOR WACH ROW
BEGIN
IF OLD.wl < NEW.wl THEN
IF NEW.wl = 3 THEN
INSERT INTO blocked(uid, time) VALUE(NEW.ID, 15);
UPDATE Users SET state=3 WHERE ID=NEW.ID;
END IF;
END IF;
END;
Now when i try to execute this query: UPDATE Users SET wl=3 WHERE ID=1
I have error:
#1442 - Can't update table 'Users' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
I hope that you understand from trigger what I want to do. I know that this trigger causes itself, but I don't have idea how to do that in other way. I tried using two trigger one After Update on Users and second After Insert On blocked, but the problem were the same.
Create a before update trigger if you want to modify the row being updated.
CREATE TRIGGER sprLog BEFORE UPDATE ON Users FOR WACH ROW
BEGIN
IF OLD.wl < NEW.wl THEN
IF NEW.wl = 3 THEN
INSERT INTO blocked(uid, time) VALUE(NEW.ID, 15);
SET NEW.state = 3;
END IF;
END IF;
END;

Can I update the just added row using MySQL triggers

The default initial value of one column in my database is the same as the row's auto-incremented id. I'm trying to use triggers to set it.
CREATE TRIGGER `default_order_value`
AFTER INSERT ON `clusters`
FOR EACH ROW
BEGIN
UPDATE `clusters` SET `order` = NEW.id WHERE `id` = NEW.id;
END
But this keeps throwing a syntax error
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 5
I've tried all sorts of permutations of this with no luck. Can anyone see what I'm doing wrong?
As zerkms said, you need to change the delimeter. But since you only use 1 line of code, you don't need the BEGIN and END. And that way, you don't need to change the delimiter either
CREATE TRIGGER `default_order_value`
AFTER INSERT ON `clusters`
FOR EACH ROW
UPDATE `clusters` SET `order` = NEW.id WHERE `id` = NEW.id;
Since you are getting an error you cannot update the row, I suggest the following:
Do NOT perform the update query at all. On default the order value = the ID value. So when the order value changes, you can update it properly.
If you are requesting the data with php, do something like this:
$order = $row['order'];
if ($order == '')
$order = $row['id'];
After you need it updating, you've got the correct value.
I don't think you can do that. An AFTER INSERT trigger cannot modify the same table, neither by issuing an UPDATE nor by something like this:
CREATE TRIGGER `default_order_value`
AFTER INSERT ON `clusters`
FOR EACH ROW
SET NEW.`order` = NEW.id ;
which results in this error:
> Error Code: 1362. Updating of NEW row is not allowed in after trigger
You can't either use a BEFORE INSERT trigger because then the NEW.id is not known (if you modify the above, the order column will get 0 value after the Insert.
What you can do, is use a transaction:
START TRANSACTION ;
INSERT INTO clusters (id)
VALUES (NULL);
UPDATE clusters
SET `order` = id
WHERE id = LAST_INSERT_ID();
COMMIT ;
You get the error because mysql treats ; in line 5 as the end of your trigger declaration, which obviously leads to the syntax error.
So you need to redefine delimiter before you specify the trigger body:
delimiter |
CREATE TRIGGER `default_order_value`
AFTER INSERT ON `clusters`
FOR EACH ROW
BEGIN
UPDATE `clusters` SET `order` = NEW.id WHERE `id` = NEW.id;
END;
|
delimiter ;
You can create just BEFORE INSERT TRIGGER, it's works like this:
CREATE TRIGGER `default_order_value`
BeFORE INSERT ON `clusters`
FOR EACH ROW
BEGIN
SET NEW.`order` = NEW.id ;
END
same as below we are using
DELIMITER $$
USE `e_store`$$
DROP TRIGGER /*!50032 IF EXISTS */ `Test`$$
CREATE
/*!50017 DEFINER = 'root'#'%' */
TRIGGER `Test` BEFORE INSERT ON `categories`
FOR EACH ROW
BEGIN
DECLARE vtype VARCHAR(250) DEFAULT NULL;
SET vtype = NEW.name;
IF (NEW.MDNAME IS NULL)
THEN
-- SET NEW.MDNAME = 'NA';
SET NEW.MDNAME=MD5(NEW.name);
END IF;
END;
$$
DELIMITER ;
This worked for me:
CREATE TRIGGER `update_table_2`
AFTER UPDATE ON `table_1`
FOR EACH ROW
UPDATE table2
JOIN table_1
SET table_2.the_column = NEW.the_column
WHERE table_2.auto_increment_field = OLD.auto_increment_field

Why do I get an "This version of MySQL doesn't yet support '...'" error?

I have a query like following:
delimiter $$
DROP TRIGGER IF EXISTS TR_SCIN_BANK_UPD$$
CREATE TRIGGER TR_SCIN_BANK_UPD
AFTER UPDATE ON SCIN_BANK
FOR EACH ROW
BEGIN
IF OLD.BANK_NAME != NEW.BANK_NAME THEN
INSERT into SCIN_BANK_LOG SET BANK_ID=OLD.BANK_ID, BANK_NAME=OLD.BANK_NAME, LAST_UPD_USER_ID=OLD.LAST_UPD_USER_ID, LAST_UPD_TS=now();
END IF;
IF OLD.BANK_DESC != NEW.BANK_DESC THEN
INSERT into SCIN_BANK_LOG SET BANK_ID=OLD.BANK_ID, BANK_DESC=OLD.BANK_DESC, LAST_UPD_USER_ID=OLD.LAST_UPD_USER_ID, LAST_UPD_TS=now();
END IF;
END$$
when executing I get
This version of MySQL doesn't yet support 'multiple triggers with the same action time and event for one table'
this error can any one provide solution for this?
I guess there already is an AFTER UPDATE trigger on that table, but it is not named TR_SCIN_BANK_UPD, meaning that your DROP TRIGGER IF EXISTS line does nothing.
Upgrading Mysql to version 5.6.27 solved it for me:
Server version: 5.6.27-0ubuntu0.14.04.1 (Ubuntu)
yes mysql dont support this if you use same event with different trigger name and at same time.
better, for this you should use if condition here : like below :
delimiter $$
create trigger trigger_name
AFTER insert
on t1
for each row
begin
if new.col1 like '%Sabcd%'
then
update t2 inner join t3 on t2.col1=t1.col1
set t2.col2=0 ;
end if;
if new.col1 like '%dcba%'
then
update t2 inner join t3 on t2.col1=t1.col1
set t2.col2=02;
end if;
end;
$$