I am trying to create a mysql trigger. The error code 1064 is very generic. The trigger is to see if a record exists for a particular key; and if it does update a particular column in the newly inserted row with that value. I am using a select query on the same table as the trigger is on. Does that cause a problem? Here is the code:
DELIMITER $$
CREATE TRIGGER classid_insert
AFTER INSERT ON courses_semester
FOR EACH ROW
BEGIN
SET #class_id = (SELECT class_id FROM courses_semester WHERE
course_id = NEW.`course_id`
AND `dept_id` = NEW.`dept_id`
AND `univ_id` = NEW.`univ_id`
AND `section_id` = NEW.`section_id`
AND `semester` = NEW.`semester`
AND `year` = NEW.`year`);
IF(#class_id = NULL)
THEN
NEW.class_id = UUID()
ELSE
NEW.class_id = #class_id
END IF;
END
DELIMITER ;
your entire trigger code should look like below. remove the spaces after DELIMITER $$ and before DELIMITER ;. Also, the last END need to changed to END $$. Also, it has to be an BEFORE trigger and not an AFTER trigger.
Moreover, NEW.class_id = UUID() is not correct.It's missing SET as
SET NEW.class_id = UUID();
CORRECTED TRIGGER CODE:
DELIMITER $$
CREATE TRIGGER classid_insert
BEFORE INSERT ON courses_semester
FOR EACH ROW
BEGIN
SET #class_id = (SELECT class_id FROM courses_semester WHERE
course_id = NEW.`course_id`
AND `dept_id` = NEW.`dept_id`
AND `univ_id` = NEW.`univ_id`
AND `section_id` = NEW.`section_id`
AND `semester` = NEW.`semester`
AND `year` = NEW.`year`);
IF(#class_id = NULL)
THEN
SET NEW.class_id = UUID();
ELSE
SET NEW.class_id = #class_id;
END IF;
END $$
DELIMITER ;
Related
Is it possible to insert a control on the data that insert in a table? In a way that satisfies a specific condition provided, otherwise not
drop function Presente;
delimiter //
create function Presente( Persona_Da_Cercare varchar(16), Data_Legge date) returns int
begin
declare risultato int;
select count(*) into risultato
from PARLAMENTARI_IN_CARICA as pic
where Persona_Da_Cercare = pic.Persona and data_Legge >= pic.Data_Eletto;
if risultato = 0
then
select count(*) into risultato
from STORICO_PARLAMENTARI as sp
where Persona_Da_Cercare = sp.Persona and data_Legge >= sp.Data_Inizio and data_Legge <= sp.Data_Fine;
end if;
return risultato;
end//
set #ultima_legge bigint;
set #ultimo_parlamentare varchar(16);
set #data_legge date;
drop trigger if exists Ultimo_Voto;
delimiter $$
create trigger Ultimo_Voto before insert on VOTO_PALESE
for each row
begin
set #ultima_legge = new.Legge;
set #ultimo_parlamentare = new.parlamentare;
set #data_legge = (select Data_Approvazione from LEGGI where Cod_Legge = new.Legge);
end $$
drop trigger if exists Controllo_Voto_Palese;
delimiter $$
create trigger Controllo_Voto_Palese after insert on VOTO_PALESE
for each row
BEGIN
IF Presente(#ultimo_parlamentare, #data_legge) = 0 THEN
delete from VOTO_PALESE where Legge = #ultima_legge AND Parlamentare = #ultimo_parlamentare;
END IF;
END $$
insert into VOTO_PALESE(Legge, Parlamentare, Voto) values(770, 'MSRMRC01C14L378X', 'astenuto');
when I run the code it gives me this error
Error Code: 1442. Can't update table 'voto_palese' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
I don't understand where the problem is
i am setting triggerafter_inser and i dont know how to resolve it
DELIMITER $$
USE `solocloud_dev_2`$$
DROP TRIGGER IF EXISTS table_10_summary_after_insert $$
CREATE TRIGGER table_10_summary_after_insert AFTER INSERT ON table_10
FOR EACH ROW BEGIN
DECLARE var INT;
SET var=0;
SELECT COUNT(*) FROM table_10_summary WHERE client_id = new.client_id;
IF var > 0
THEN
UPDATE table_10_summary SET records = records+1 WHERE client_id = new.client_id;
ELSE
INSERT INTO table_10_summary (new.client_id,1);
END$$
DELIMITER$$
There are several problems with your trigger :
you need to SET var from the results of the query ; as it is now, you are not setting this value
the IF block must be terminated with END IF
The following codes compiles successfully in this DB Fiddle :
DELIMITER $$
DROP TRIGGER IF EXISTS table_10_summary_after_insert $$
CREATE TRIGGER table_10_summary_after_insert AFTER INSERT ON table_10
FOR EACH ROW
BEGIN
DECLARE var INT;
SET var = (SELECT COUNT(*) FROM table_10_summary WHERE client_id = new.client_id);
IF (var > 0) THEN
UPDATE table_10_summary SET records = records + 1 WHERE client_id = new.client_id;
ELSE
INSERT INTO table_10_summary VALUES(new.client_id,1);
END IF;
END$$
DELIMITER ;
I have a MySQL table , look like this
t id lang title
1 7 en_UK my_title
1 7 kh_KH
I want write a trigger that update title to my_title with the same id is 7
Result
t id lang title
1 7 en_UK my_title
1 7 kh_KH my_title
From my understanding.
DELIMITER $$
CREATE TRIGGER upd_title BEFORE UPDATE ON `term`
FOR EACH ROW BEGIN
IF (NEW.title IS NULL OR NEW.title= '') THEN
SET NEW.title= ??? ;
END IF;
END$$
DELIMITER ;
[UPDATE1]->not works (trigger not being created)
DELIMITER $$
DROP TRIGGER IF EXISTS `update_category_after_insert`
CREATE TRIGGER `update_category` AFTER INSERT ON `categories`
FOR EACH ROW BEGIN
DECLARE loc_title text;
IF (NEW.libelle_categorie IS NULL OR NEW.libelle_categorie= '') THEN
select libelle_categorie into loc_title from categories where NEW.num_noeud= num_noeud and langue = 'en_UK';
SET NEW.libelle_categorie = loc_title;
END IF;
END
DELIMITER ;
[UPDATE2]
DELIMITER $$
CREATE TRIGGER ``update_category_after_insert`` BEFORE INSERT ON `categories`
FOR EACH ROW BEGIN
DECLARE loc_title text;
IF (NEW.libelle_categorie IS NULL OR NEW.libelle_categorie= '') THEN
select libelle_categorie into loc_title from categories where NEW.num_noeud= num_noeud and langue = 'en_UK';
SET NEW.libelle_categorie = loc_title;
END IF;
END
DELIMITER ;
Finally , I found the good solution for my case
UPDATE categories c INNER JOIN categories c2 ON (
c.num_noeud = c2.num_noeud
) SET c.libelle_categorie = c2.`libelle_categorie`
Can you clarify?
Are you trying to pull the value from the title column in the 'en_UK' row that exists when you insert an new row with the same id that HAS the title column not entered?
okay
CREATE TRIGGER upd_title BEFORE UPDATE ON `term`
FOR EACH ROW BEGIN
DECLARE loc_title VARCHAR(20);
IF (NEW.title IS NULL OR NEW.title= '') THEN
select title into loc_title from term where NEW.id = id and lang = 'en_UK';
SET NEW.title= loc_title;
END IF;
END
This should do the trick.
This was my trigger def:
CREATE DEFINER = CURRENT_USER TRIGGER `therinks`.`glreturndata_BEFORE_UPDATE` BEFORE UPDATE ON `glreturndata` FOR EACH ROW
BEGIN
DECLARE myVal VARCHAR(20);
if NEW.DESCRIPTION IS NULL or new.description = '' THEN
SELECT min(description) into myVal from glreturndata where category = NEW.category and new.idglreturndata <> idglreturndata;
Set NEW.DESCRIPTION = myval;
end if;
END
It seems that you can't do all this in a trigger. According to the 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.
According to this answer, it seems that you should:
create a stored procedure, that inserts into/Updates the target table, then updates the other row(s), all in a transaction.
With a stored proc you'll manually commit the changes (insert and update). I haven't done this in MySQL, but this post looks like a good example.
I hoped something as below will be successful. But SQL syntax error...
Clearly i don't want to insert data into a table if only a special data is changed.
CREATE TRIGGER `before_access_update` BEFORE UPDATE ON `access` FOR EACH ROW IF NOT (NEW.pin<>OLD.pin) THEN
INSERT INTO access_audit
SET action = 'update',
a_lastname = OLD.lastname,
a_firstname = OLD.firstname,
changed_on = NOW();
END IF;
You use a ; in your trigger, therefore you have to use another query delimiter for the trigger itself:
DELIMITER $$
CREATE TRIGGER `before_access_update` BEFORE UPDATE ON `access` FOR EACH ROW IF NOT (NEW.pin<>OLD.pin) THEN
INSERT INTO access_audit
SET action = 'update',
a_lastname = OLD.lastname,
a_firstname = OLD.firstname,
changed_on = NOW();
END IF$$
DELIMITER ;
I have liquibase set up. I currently have 4-5 triggers I would like to load, with each trigger stored in a separate file. All of the triggers are on separate tables. However I keep getting this error:
SEVERE 9/17/13 12:05 PM:liquibase: Change Set migrations/09-16-2013-16-10.sql::129 failed. Error: Error executing SQL DELIMITER $$
DELIMITER $$
CREATE TRIGGER `UPDATE_tableA` BEFORE UPDATE on `tableA`
FOR EACH ROW BEGIN
IF (OLD.ColumnA = NEW.ColumnA) and
((OLD.ColumnB is null and NEW.ColumnB is null) or (OLD.ColumnB = NEW.ColumnB)) and
((OLD.ColumnB is null and NEW.ColumnB is null) or (OLD.ColumnB = NEW.ColumnB)) and
((OLD.ColumnC is null and NEW.ColumnC is null) or (OLD.ColumnC = NEW.ColumnC))
THEN
SET NEW.ColumnA = 0;
SET NEW.ColumnB = NULL;
SET NEW.ColumnB = NULL;
SET NEW.ColumnC = NULL;
END IF;
END$$
DELIMITER ;
DELIMITER $$
CREATE TRIGGER `UPDATE_tableB` BEFORE UPDATE on `tableB`
FOR EACH ROW BEGIN
IF (OLD.ColumnA = NEW.ColumnA) and
((OLD.ColumnB is null and NEW.ColumnB is null) or (OLD.ColumnB = NEW.ColumnB)) and
((OLD.ColumnB is null and NEW.ColumnB is null) or (OLD.ColumnB = NEW.ColumnB)) and
((OLD.ColumnC is null and NEW.ColumnC is null) or (OLD.ColumnC = NEW.ColumnC))
THEN
SET NEW.ColumnA = 0;
SET NEW.ColumnB = NULL;
SET NEW.ColumnB = NULL;
SET NEW.ColumnC = NULL;
END IF;
END$$
DELIMITER ;
'endDelimiter' is a regExp so try this instead
<sqlFile endDelimiter="\$\$" path="..."/>
DELIMITER $$ is a command understood by the MySQL client parser, but not through JDBC that Liquibase uses.
You need to specify the delimiter in how you reference the file, perhaps as <sqlFile endDelimiter="$$" path="..."/>