i'm working on a proyect in mysql and i can't made things work between 2 triggers, what i'm trying to do is
1)
Create a trigger that after inserting values in a table update the data of another table, working
2)
Create a trigger that after updating the aforementioned table, delete the row that detonated the first trigger, not working
I searched the documentation, examples, tutorials, goolge and of course in different posts of the site, but I have not found anything that can guide me or help to solve my problem :(
For the moment i have this
1)
CREATE TRIGGER update1 BEFORE INSERT ON table1
FOR EACH ROW
UPDATE table2 SET table2.value = table2.value +
NEW.value WHERE ac_id = NEW.acc_id
2)
CREATE TRIGGER `delete` AFTER UPDATE ON table2
FOR EACH ROW DELETE FROM table1 WHERE table1.acco_id =
NEW.acc_id
Individually both work, but if I make an insert in table1 the following message appears
Can't update table 'table1' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
sorry for my bad English, any help will be highly appreciated, thanks in advance
The observed error message:
ERROR 2442 (HY000) Can't update table '%s' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
is expected behavior. The triggers shown in the question violate a documented restriction:
A stored function or trigger cannot modify a table that is already being used (for reading or writing) by the statement that invoked the function or trigger.
Reference: https://dev.mysql.com/doc/refman/5.7/en/stored-program-restrictions.html
To focus that on the specific triggers shown in the question, in the context of a trigger fired by an insert into table1, it is not possible to delete rows from table1. There is no workaround to this restriction.
To "solve this problem" means to step back from the current design, and come up with a different design which achieves the objectives.
Related
Am populating a table using a trigger after an insert event occurs on another table and that worked fine. However i then noticed that the trigger would still insert a new row for existing records. To fix this, I want to create the trigger again but this time it would only fire if a condition is met...but not having previously used triggers in the past am getting a syntax error and not able to identify what am doing wrong. Kindly have a look and help me fix this
CREATE TRIGGER `students_gen_insert`
AFTER INSERT ON `students` FOR EACH ROW
BEGIN
INSERT INTO records (student_id, subject_id)
SELECT new.student_id, subjects.subject_id
FROM subjects
WHERE category = new.class;
END;
Am currently using MySql 5.6.17 version.
It is generally not a good idea to SELECT from the table the trigger is on, and forbidden to UPDATE or INSERT (not that you are doing those). Assuming you are trying to get the values for the row just inserted, the first SET ... SELECT you have is needless; just use NEW.fieldname to get the fields of the inserted row.
The second SET ... SELECT and following condition are a bit confusing. If referential integrity is being maintained, I would think it would be impossible for the records table to refer to that particular student_id of the students table at the point the trigger is executed. Perhaps this was to avoid the duplicate inserts from the trigger's previous code? If so, it might help for you to post that so we can pinpoint the actual source of redundant inserts.
In MySQL, I have just made this trigger to set the last modified date of one table if a new record relating to it is inserted into a linking table
create trigger trg_badge after insert on tbl_badge for each row
UPDATE tbl_sub_model SET last_modified_date = NOW()
WHERE sub_model_sk = NEW.sub_model_sk;
When I run a script that fills tbl_sub_model then tbl_badge I get:
Error Code: 1442. Can't update table 'tbl_sub_model' in stored
function/trigger because it is already used by statement which
invoked this stored function/trigger.
Things work fine when I insert using a separate script but just not if both statements are in the same script. is there a way of inserting into both tables with the same .sql script?
Ah... solved it, my insert statement was joining tbl_sub_model to a couple of other ones in order to get the sub_model_sk relating to the correct new records.
Now I know that I'll just create the triggers at the end of the script, no biggie.
I have two tables one called fs_note the other called dumy_fs_note
I created after Insert and after Delete triggers on the fs_table that insert a row with calculated data to the dumy_fs_table that has an after insert trigger that should update a certain row in fs_table with the new values The problem is that now i am having error: #1442 Can't update table 'fs_note' in stored function/trigger because it is already used by statement which invoked this stored function/trigger. why is that?? it is the dumy_fs_note table that is trying to update the fs_table not the same table, Any idea what's wrong?
Thanks in advance
Yeah, you just can't do that. Mysql is this way preventing circular loops and memory issues... It is like updating a cursor being parsed: some engines allow it, others no.
I'm trying to create a database with history in mind (experience shows you'll have to do this one day or another).
I've asked here database-design-how-to-handle-the-archive-problem but there's no better anser than the link here.
My problem is about where to do the code and technically, how (MySQL gives me headaches). First I've started doing this in Php: before doing any insert, duplicate the record mark it as "obsolete" then modify the record.
But there's a dependency problem (manytomany and manytoone associations must be updated as well) which implies coding (one way or another) all the dependancies and updates that come with the tables (which is not acceptable).
So I'm thinking about doing all the work on the database server side. This would greatly simplify my Php code.
The problem is that I have to "archive" the current record before modifying it. To do so, the code must be in a trigger "before update".
Here's my code:
DELIMITER ;;
DROP TRIGGER IF EXISTS produit_trigger_update_before;
CREATE TRIGGER produit_trigger_update_before
BEFORE UPDATE ON produit
FOR EACH ROW BEGIN
/* */
INSERT INTO produit SET
id_origine = OLD.id_origine,
date_v_creation = OLD.date_v_creation,
date_v_start = OLD.date_v_debut,
date_v_end = NOW(),
...
last_record = OLD.last_record;
/* Dependancies : */
SET #last=LAST_INSERT_ID();
UPDATE categorie_produit SET id_produit=#last
WHERE id_produit = OLD.id;
UPDATE produit_attribut SET id_produit=#last
WHERE id_produit = OLD.id;
END;;
DELIMITER ;;
If I get this code working, all my problems are gone. But damn it, it's not working:
mysql> update produit set importance=3;
ERROR 1442 (HY000): Can't update table 'produit' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
mysql> Bye
In this page there's a working sample, which uses INSTEAD OF UPDATE clause in the trigger. MySQL doesn't seem to support this.
So my question is both conceptual (= have you any other "principle" that could work) and/or technical (= can you make this trigger work).
If I get this code working, all my problems are gone. But damn it, it's not working:
As a rule you can't have a trigger on table A trigger inserts into table A - since that could cause an endless loop. (Trigger mutation in Oracle terms)
Personally I would not do this using triggers. Triggers can do "audit logging" - but this is not what you want here.
I suggest you solve it programatically - either with a PHP function or a MySQL stored procedure (whatever your preference) that you call something like "ModifyProduit".
The code would then do basically what you have the trigger above do. (It might be easier to just have the code set date_v_end on the current row, and then insert a completly new row. That way you don't have to mess around with updating your referenced tables)
you can do history of a table with an auxiliary table like this (i've done this for many tables on mysql and the speed is very good):
table produit_history has the same structure as produit + 2 additional columns: "history_start DATETIME NOT NULL" and "history_stop DATETIME DEFAULT NULL".
there are 3 triggers on produit table:
AFTER INSERT: in this trigger there is a simple insert into produit_history of the same data with history_start = NOW() and history_stop = NULL (NULL means the current row is valid)
AFTER UPDATE: this trigger performs two queries. The first is un update like this:
UPDATE produit_history set history_stop = NOW() WHERE id_origine = OLD.id_origine AND history_stop IS NULL;
The second query is an insert identical to the one in the AFTER INSERT trigger.
AFTER DELETE: this triggers there is a simple update which is identical to the one in the AFTER UPDATE.
You can then query this history table and obtain snapshots at whatever time you're interested in with the following where condition:
WHERE (history_start <= "interesting_time" AND (history_stop IS NULL OR history_stop > "interesting_time"))
After creating either of the triggers below I get the error (detailed after the code) when I try to do an update. No matter which way I go I seem to be unable to update the table. Do I have to create a new table and put one column in that for updating or is there a way around this? This page says: "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." But then what's the point of the NEW and OLD keywords? Am I just using them incorrectly?
table: gallery
columns: weight, modifier, rating
trigger: updateRating
CREATE TRIGGER updateRating
BEFORE UPDATE ON gallery
FOR EACH ROW
UPDATE gallery SET rating= sum(NEW.weight * NEW.modifier)
or
CREATE TRIGGER updateRating
AFTER UPDATE ON gallery
FOR EACH ROW
UPDATE gallery SET rating= sum(weight * modifier)
SQL query: Edit
UPDATE `acs`.`gallery` SET `weight` = '6' WHERE `gallery`.`id` =1 LIMIT 1
MySQL said: Documentation
#1442 - Can't update table 'gallery' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
Right, error means that you cannot modify gallery table because the trigger was defined with this table. There is one possible way to update the value, it is a BEFORE UPDATE trigger, here it is an example -
CREATE TRIGGER updateRating
BEFORE UPDATE
ON gallery
FOR EACH ROW
BEGIN
SET NEW.rating= NEW.weight * NEW.modifier; -- You may update a NEW value.
END
At the end, let me ask a question. Why are you going to use a trigger to modify the rating? I want to say that you can calculate rating on the fly, in SELECT statement.