I have this code here:
CREATE TRIGGER testTrigger
AFTER INSERT ON users
BEGIN
DECLARE #uid VARCHAR(60)
SET #uid = (SELECT userid FROM inserted)
INSERT INTO user_locations (id,uid,lat,lng) VALUES (0,#uid,5.0,5.0)
END;
The idea is to insert generated user id into other table alongside some other data as soon as it hits the first 'users' table but phpMyAdmin gives this error code:
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
BEGIN
DECLARE #uid VARCHAR(60)
SET #uid = (SELECT userid FROM inserted)
at line 3
Can someone clarify why this trigger is bad?
I see four problems:
You have to use DELIMITERs so that your able to finish the commands with a semicolon as usual.
FOR EACH ROW is missing.
Use new.uid to access the recently inserted uid.
I'd also suggest using procedure variables instead of session-specific user-defined #variables, the latter ones being loosely typed and not declared as you've done.
But you don't even have to declare a variable. If you don't use phpMyAdmin:
DELIMITER //
CREATE TRIGGER testTrigger
AFTER INSERT ON users FOR EACH ROW
BEGIN
INSERT INTO user_locations (id,uid,lat,lng) VALUES (0,new.uid,5.0,5.0);
END//
DELIMITER ;
Check this answer about delimiter and the MySQL 5.7 docs on triggers and this answer about variables.
Edit, I overread you're using phpMyAdmin:
I don't use phpMyAdmin. But you can (stolen from here)
In phpMyAdmin, select the database that you want to work with.
Go to the SQL tab at the top of the page.
In the "Run SQL query/queries on database" form, change the Delimiter to $$. (Located in a small box at the bottom of the form)
Enter your SQL trigger into the main dialog box on the form. The correct syntax is as follows:
CREATE TRIGGER testTrigger
AFTER INSERT ON users FOR EACH ROW
BEGIN
INSERT INTO user_locations (id,uid,lat,lng) VALUES (0,new.uid,5.0,5.0);
END;$$
Hit "GO" with Super privilege.
i am trying to create a trigger to concatenate my table columns into a single column but i can't find the error.
code:
create trigger molecule_trigger After insert on molecule
For each row
begin
Update molecule
Set molecule_text= CONCAT(mid,',',ULCHEm_ID,',',IUPAC_name,',',Inchi,',',inchi_key,',',smiles,',',can_smiles,',',Molecular_formula,',',Molecular_weight,',',vendor,',',CAS,',',links,',',image);
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 '' at line 6
You get this error, because you started a "multiple statements" block with begin, but the ; after your update statement terminates the create trigger statement before the end; statement.
You have to either change the delimiter
DELIMITER $$
create trigger molecule_trigger After insert on molecule
For each row
begin
Update molecule
Set molecule_text= CONCAT(mid,',',ULCHEm_ID,',',IUPAC_name,',',Inchi,',',inchi_key,',',smiles,',',can_smiles,',',Molecular_formula,',',Molecular_weight,',',vendor,',',CAS,',',links,',',image);
end $$
DELIMITER ;
Or you remove the begin and end.
create trigger molecule_trigger After insert on molecule
For each row
Update molecule
Set molecule_text= CONCAT(mid,',',ULCHEm_ID,',',IUPAC_name,',',Inchi,',',inchi_key,',',smiles,',',can_smiles,',',Molecular_formula,',',Molecular_weight,',',vendor,',',CAS,',',links,',',image);
Now, you have another problem. You're trying to do an action in the trigger on the same table as your trigger works on. This is not allowed. Change your trigger to this:
create trigger molecule_trigger BEFORE insert on molecule
For each row
SET NEW.molecule_text= CONCAT_WS(',', NEW.mid, NEW.ULCHEm_ID, NEW.IUPAC_name, NEW.Inchi, NEW.inchi_key, NEW.smiles, NEW.can_smiles, NEW.Molecular_formula, NEW.Molecular_weight, NEW.vendor, NEW.CAS, NEW.links, NEW.image);
Note though, that this sets the molecule_text only for the columns inserted. Your trigger updated the whole table each time a row is inserted. And if you insert 3 rows in one statement, your table gets updated 3 times. This is not what you want to do anyway :)
My trigger fails when i try to insert a new row in my table because Mysql doesn't support updating rows in the same table the trigger is assigned to. Does anyone have suggestions on a good workaround/alternative?
My trigger:
-- Trigger DDL Statements
DELIMITER $$
CREATE TRIGGER check_sequence
BEFORE INSERT ON data FOR EACH ROW
BEGIN
IF EXISTS(SELECT TRUE FROM data WHERE sequence = NEW.sequence) THEN
UPDATE data SET sequence=sequence+1 WHERE sequence >= NEW.sequence;
END IF;
END $$
DELIMITER ;
Error Sql that is displayed when i try to insert new row:
ERROR 1442 (HY000): Can't update table 'data' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
Thanks for answer,
In MySQL, You can't update (or insert in) table A in a trigger for table A.
http://dev.mysql.com/doc/refman/5.0/en/stored-program-restrictions.html
You can try a sproc and use a transaction, or consider PostgreSQL, which can do this.
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.
Well, I have researched and have not found a solution to the following problem 'SQL Error (1442): Can not update table' messages' in stored function / trigger because it is already used by statement Which invoked this stored function / trigger. `
My trigger is created, only when I run the INSERT on the table of messages, this error is thrown, my trigger is
DELIMITER $$
DROP TRIGGER IF EXISTS `onMessage` ;
CREATE TRIGGER `onMessage` BEFORE INSERT ON `messages` FOR EACH ROW
BEGIN
UPDATE `users` SET `users`.`messages` = ( `users`.`messages` + 1 )
WHERE `users`.`uid` = NEW.uid ;
DELETE FROM `messages` WHERE `date` < ( NOW( ) - INTERVAL 1 MINUTE ) ;
END ;
$$
DELIMITER ;
This is a restriction in the use of triggers.
From the MySql documentations:
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.
Correct, for MySQL anyway
You can't write to the table associated with a trigger in that trigger. It generates all manner of inconsistencies, not least because MySQL triggers are processed row-by-row (RBAR)
In this case, I'd use a stored procedure to deal with the INSERT on messages
It is not possible to update a table for which the trigger is created in the trigger since Mysql does some locking stuff on that table. Therefore you can't insert/update/delete rows of the same table because then the trigger would called again and again, ending up in a recursion.
If you want to create a trigger on the table which will update itself (perfoming a deletion in this case), make sure you use the NEW.column_name to refer to the row after it’s updated.