Updating joined rows in two tables from an INSERT trigger - mysql

I currently have the following MySQL query, which I would like to include in a trigger, rather than as a separate query. The query updates data in two tables which are joinable:
UPDATE `testing_names` INNER JOIN `purchase_names`
ON `testing_names`.`fulldomain` = `purchase_names`.`fulldomain`
SET
`testing_names`.`account_id` = `purchase_names`.`account_id`,
`purchase_names`.`purchase_status` = 1
WHERE `purchase_names`.`purchase_status` = 0
A row is (separately) inserted into testing_names. This row SHOULD have a corresponding entry in purchase_names. After a row is inserted into testing_names, when my UPDATE query is next run, it will update testing_names.account_id and update purchase_names.purchase_status to effectively mark this task as completed.
It makes sense to run this as part of a trigger, but I haven't been able to create a trigger that does the job.
So far, I have successfully created a trigger:
DELIMITER $$
CREATE TRIGGER `my_trigger` AFTER INSERT
ON testing_names
FOR EACH ROW BEGIN
UPDATE `testing_names` INNER JOIN `purchase_names`
ON `testing_names`.`fulldomain` = `purchase_names`.`fulldomain`
SET
`testing_names`.`account_id` = `purchase_names`.`account_id`,
`purchase_names`.`purchase_status` = 1
WHERE `purchase_names`.`purchase_status` = 0;
END$$
DELIMITER ;
but evidently running a new UPDATE query is not allowed, because upon inserting a row, I get an error: #1442 - Can't update table 'testing_names' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.

Unfortunately, a trigger on a table cannot update the same table.
From MySQL documentation:
Within a stored function or trigger, it is not permitted to modify a table that is already being used (for reading or writing) by the statement that invoked the function or trigger.
Instead, you might be able to complete your update by having the trigger on testing_names update purchase_names and have another trigger on purchase_names update testing_names.

Try Using a Before INsert Instead

Related

Use Procedure instead of trigger in MySQL

I'm trying to make trigger to update one field in inserted row but even with this answer: https://stackoverflow.com/a/15300941/4018940 i cant make it work.
Every time i get error:
General error: 1442 Can't update table 'people' in stored
function/trigger because it is already used by statement which invoked
this stored function/trigger
Here is my code:
CREATE TRIGGER short_name_trigger
BEFORE INSERT ON `people`
FOR EACH ROW BEGIN
UPDATE `people` SET NEW.short_name = "wohahaha";
END
Is there any chance that stored procedure will make it work?
How to write that procedure?
If you want to change the value being inserted in the new row, you don't need to use UPDATE people. Just set NEW.short_name and this will replace the value that's being inserted.
CREATE TRIGGER short_name_trigger
BEFORE INSERT ON `people`
FOR EACH ROW BEGIN
SET NEW.short_name = "wohahaha";
END

Mysql triggers Create error

This is my create triggers . I want when Insert vhftofass it execute this query(UPDATE vhf_msg_rx SET msg_text="";) that means Its make Null this table vhf_msg_rx.But when i write that query after insert Query it make error (Can't update table 'vhf_msg_rx' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.) Please help me how can i do this
CREATE
/*!50017 DEFINER = 'root'#'localhost' */
TRIGGER `VHFtoFASS` AFTER UPDATE ON `vhf_msg_rx`
FOR EACH ROW BEGIN
INSERT INTO vhftofass SELECT NULL,msg_text,NOW(),0 FROM vhf_msg_rx WHERE msg_text<>"";
END;
$$
I'm not completely clear on what you're trying to do, but it seems like you want to copy modified rows of one table into another, but only retaining certain fields. You could do that by referencing the inserted record with NEW.columnname inside the FOR EACH ROW loop, for example
CREATE TRIGGER `VHFtoFASS` AFTER UPDATE ON `vhf_msg_rx`
FOR EACH ROW BEGIN
INSERT INTO vhftofass VALUES(NULL,NEW.msg_text,NOW(), 0);
END;
Note that this will only handle updates - you'll need an INSERT trigger to capture new rows.

Updating DATETIME with trigger, get error 1442 in MySQL

I am having trouble with a trigger in MySQL. I have a column named "last_modified" that I want to be automatically updated with the current date and time when it is the table is edited. Using a trigger, this is my SQL query:
delimiter //
CREATE TRIGGER trg_update_responders BEFORE UPDATE ON survey_responders
FOR EACH ROW
BEGIN
UPDATE survey_responders
SET NEW.last_modified = CURRENT_DATETIME();
END;//
However, when I update the table, such as with this query:
UPDATE survey_responders SET first_name = "bob" WHERE id = "1";
MySQL Workbench displays error 1442: "Can't update table 'table_name' in stored function/trigger because it is already used by statement which invoked this stored function/trigger"
I have looked at similar questions with the same error but still have not fixed it. Help is appreciated.
** UPDATE **
This did the trick:
delimiter //
CREATE TRIGGER trg_update_responders BEFORE UPDATE ON survey_responders
FOR EACH ROW
BEGIN
SET NEW.last_modified = CURRENT_TIMESTAMP();
END;//
Seems like I simply did not need to repeat the
UPDATE survey_responders
and CURRENT_DATETIME() did not exist, I had to use CURRENT_TIMESTAMP().
This did the trick:
delimiter //
CREATE TRIGGER trg_update_responders BEFORE UPDATE ON survey_responders
FOR EACH ROW
BEGIN
SET NEW.last_modified = CURRENT_TIMESTAMP();
END;//
Seems like I simply did not need to repeat the
UPDATE survey_responders
and CURRENT_DATETIME() did not exist, I had to use CURRENT_TIMESTAMP().
What you are trying to do is not possible using a trigger.
Within a stored function or trigger, it is not permitted to modify a
table that is already being used (for reading or writing) by the
statement that invoked the function or trigger.
Source
You need to do this some other way.
See here: MySQL - Trigger for updating same table after insert
The typical way to do that, is to create a stored procedure, that
inserts into/Updates the target table, then updates the other row(s),
all in a transaction.

MySQL Trigger cannot update table - getting ERROR 1442

I have the following trigger:
CREATE TRIGGER sum
AFTER INSERT
ON news
FOR EACH ROW
UPDATE news SET NEW.sum = (NEW.int_views + NEW.ext_views)/NEW.pageviews
It sums the int_views and ext_views column of a table and divides them by the total pageviews.
Whenever I try to add a new row to news, I get the following error:
ERROR 1442 (HY000) at line 3: Can't update table 'news' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
The trigger seems pretty simple to me. Is there a reason why the trigger fails to run?
The symptom is, that you are running an UPDATE (for all rows) inside a INSERT trigger - both modify the table, which is not allowed.
That said, if I guess the intention of your trigger correctly, you do not want to update all rows, but only the newly inserted row. You can achieve that easily with
CREATE TRIGGER sum
BEFORE INSERT
ON news
FOR EACH ROW
SET NEW.sum = (NEW.int_views + NEW.ext_views)/NEW.pageviews
Mind that this is a BEFORE INSERT trigger, as you want to change the row before it is written to the table.
If you try to update/insert on the same table that cause trigger to fire do not use the common sql command like
-> UPDATE TABLE_NAME SET COLUMN_NAME = VALUE WHERE CONDITION_LIST;
-> INSERT INTO TABLE_NAME VALUES("VALUE1","VALUE2");
This will not work. Only use set to assign the value of the column you update.
Example:
CREATE TRIGGER trigger_name BEFORE/AFTER INSERT/UPDATE ON table_name
FOR EACH ROW
SET NEW.COLUMN_NAME = "VALUE";
I was in a similar condition where I had to run two triggers:
UPDATE 3 fields on INSERTing a new ROW
UPDATE 3 fields on UPDATEing a ROW
After lot of efforts, I was finally able to write the TRIGGER in following way:
FOR updating values on INSERT
CREATE TRIGGER `INSERT_DISCOUNT_SERVICES` BEFORE INSERT ON `services`
FOR EACH ROW SET
NEW.discount_5_rate = (NEW.ndis_rate*0.05),
NEW.discount_10_rate=(NEW.ndis_rate*0.10),
NEW.discount_15_rate=(NEW.ndis_rate*0.15)
Similarly
FOR updating values on UPDATE
CREATE TRIGGER `UPDATE_DISCOUNTS_SERVICES` BEFORE UPDATE ON `services`
FOR EACH ROW SET
NEW.discount_5_rate = (NEW.ndis_rate*0.05),
NEW.discount_10_rate=(NEW.ndis_rate*0.10),
NEW.discount_15_rate=(NEW.ndis_rate*0.15)

How can I get an after update trigger to work when it is being fired from an after insert trigger in mysql?

Hello, every one :)!
I'll try and keep this as simple as possible, basically, I have one table that references itself via a parent_id column. Each row in the table can have a parent and can keep count of how many children it has via the count column. So essentially what I'm trying to do is have the triggers update each parent row's count column when necessary
The problem is that the update trigger gets called when the update operation in the insert trigger gets called. Then I get:
"General error: 1442 Can't update table 'term_taxonomies' in stored function/trigger because it is already used by statement which invoked this stored function/trigger".
Any ideas?
Actual code:
TRIGGER `dbname`.`ai_term_taxonomies`
AFTER INSERT ON `dbname`.`term_taxonomies`
FOR EACH ROW
BEGIN
IF NEW.parent_id NOT 0 THEN
UPDATE term_taxonomies as termTax SET assocItemCount = (assocItemCount + 1)
WHERE termTax.term_taxonomy_id = NEW.parent_id;
END IF;
END$$
CREATE
TRIGGER `dbname`.`au_term_taxonomies`
AFTER UPDATE ON `dbname`.`term_taxonomies`
FOR EACH ROW
BEGIN
IF NEW.parent_id NOT OLD.parent_id THEN
IF NEW.parent_id NOT 0 THEN
UPDATE term_taxonomies as termTax SET assocItemCount = (assocItemCount + 1)
WHERE termTax.term_taxonomy_id = NEW.parent_id;
END IF;
IF OLD.parent_id NOT 0 THEN
UPDATE term_taxonomies as termTax SET assocItemCount = (assocItemCount - 1)
WHERE termTax.term_taxonomy_id = OLD.parent_id;
END IF;
END IF;
END$$
All mysql triggers execute in the same transaction as the triggering statement.
You want to update using the SET NEW.assocItemCount syntax as opposed to performing an UPDATE statement on the underlying table.
Edit: However, in your case this is not possible because you are updating a different row in the same table, the hardest thing to do in a mysql trigger. Sorry.
You will have to change your schema. Take assocItemCount out of your table, create a new table holding just term_taxonomy_id and assocItemCount, and update that using an UPDATE statement from your query. It is also possible to use a view joining these two tables to hide this detail if a query needs to use your original schema.
Alternatively, if you did not have assocItemCount in your database at all, you would still be able to compute it in any queries, and your database would be better normalized than it is now.