My sql trigger, syntax error - mysql

I want to update two columns after current row update by trigger.
endtime and starttime are datetime type. duration is integer and it will represent num of seconds. Sequel Pro tell me "[ERROR in query 1] 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
Execution stopped!"
CREATE TRIGGER `end_time_update` AFTER UPDATE ON `mytable`
FOR EACH ROW
BEGIN
UPDATE mytable
set endtime = now(), duration = TIMESTAMPDIFF(SECOND, starttime, endtime)
where id = new.id;
END;

You need to change the delimiter. Otherwise the DB will terminate the definition of the trigger at the first ;
delimiter |
CREATE TRIGGER `end_time_update` BEFORE UPDATE ON `mytable`
FOR EACH ROW
BEGIN
if NEW.some_col <> OLD.some_col
then
set NEW.endtime = now();
set NEW.duration = TIMESTAMPDIFF(SECOND, NEW.starttime, NEW.endtime);
end if;
END
|
delimiter ;
You can't put an update on the same table in the trigger. That would create an endless loop. But you can use NEWto refer to the current record to modify it.

You should set your delimiter so that the semi-colons inside the trigger won't be interpreted as the end of the trigger:
-- Set the delimiter
DELIMITER $$
CREATE TRIGGER `end_time_update` AFTER UPDATE ON `mytable`
FOR EACH ROW
BEGIN
UPDATE mytable
set endtime = now(), duration = TIMESTAMPDIFF(SECOND, starttime, endtime)
where id = new.id;
END;
$$
-- Reset the delimiter
DELIMITER ;

Related

#1064 - You have an error in your SQL syntax at line 7

enter code here
DELIMITER $$
DROP TRIGGER IF EXISTS `Update_Status`$$
CREATE TRIGGER `Update_Status` AFTER INSERT ON `occurance_time`
FOR EACH ROW BEGIN
IF NOT EXISTS (SELECT `F_Seen` FROM `Total_Hours` WHERE (`SSN`=new.`SSN` and `Day_Date`=new.`Day_Date`))
THEN
INSERT INTO `total_time` (`SSN`,`Name`,`Day_Date`,`F_Seen`) VALUES(new.`SSN`,new.`Name`,new.`Day_Date`,new.`Cap_time`);
ELSE
UPDATE `total_time` SET(`L_Seen`=new.`Cap_time`) WHERE (`SSN`=new.`SSN` and `Day_Date`=new.`Day_Date`);
END$$
I have Created this After insert trigger On Occurrence _time I want to store first time of occurrence of a day and last time of occurrence of Day in Total_time table but getting this Error
"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 '(L_Seen=new.Cap_time) WHERE (SSN=new.SSN and Day_Date=new.`Day_Date...' at line 7" ***
Instead of SET(L_Seen=new.Cap_time) Please use SET L_Seen=new.Cap_time. You missed end if also. Below code is working.
CREATE TRIGGER `Update_Status` AFTER INSERT ON `occurance_time`
FOR EACH ROW
BEGIN
IF NOT EXISTS (SELECT `F_Seen` FROM `Total_Hours` WHERE `SSN`=new.`SSN` and `Day_Date`=new.`Day_Date`)
THEN
INSERT INTO `total_time` (`SSN`,`Name`,`Day_Date`,`F_Seen`) VALUES(new.`SSN`,new.`Name`,new.`Day_Date`,new.`Cap_time`);
ELSE
UPDATE `total_time` SET `L_Seen`=new.`Cap_time` WHERE `SSN`=new.`SSN` and `Day_Date`=new.`Day_Date`;
end if;
end
DB-Fiddle:
create table occurance_time(SSN varchar(50),Name varchar(50),Day_Date date,Cap_time time);
CREATE TRIGGER Update_Status AFTER INSERT ON occurance_time
FOR EACH ROW BEGIN
IF NOT EXISTS (SELECT F_Seen FROM total_time WHERE SSN=new.SSN and Day_Date=new.Day_Date)
THEN
INSERT INTO total_time (SSN,Name,Day_Date,F_Seen) VALUES(new.SSN,new.Name,new.Day_Date,new.Cap_time);
ELSE
UPDATE total_time SET L_Seen=new.Cap_time WHERE SSN=new.SSN and Day_Date=new.Day_Date;
end if;
end
db<>fiddle here

MYSQL Trigger Get Last Row Value and Set

I have been having a problem with this one. Granted this is the first trigger I have ever made (pretty new to this). I think it's a formatting issue. I have a table called filleradown. I need for every time a record is inserted to check if the value of B3_4_5 in the new row is a 1. If it is I need it to then run a select to find the last entry that B3_4_5 was a 0. Then update the NEW.stoptime value to be the 'time' value of the last 0 record.
I think I have all the parts there, but can't seem to get it to run. Please help.
DELIMITER $$
CREATE TRIGGER downinsert
BEFORE INSERT ON 'filleradown' FOR EACH ROW BEGIN
DECLARE downtime DATETIME;
IF (NEW.B3_4_5 = '1') THEN
SELECT time INTO downtime FROM filleradown WHERE B3_4_5 = 0 ORDER BY time DESC LIMIT 1;
SET NEW.stoptime = downtime;
END IF
$$
DELIMITER ;
UPDATE: I got the code a little better here, but still getting some errors.
DELIMITER $$
CREATE TRIGGER downinsert BEFORE INSERT ON filleradown
FOR EACH ROW
BEGIN
DECLARE dt DATETIME;
IF NEW.B3_4_5 = '1' THEN
SELECT MAX(time) INTO dt FROM filleradown WHERE filleradown.B3_4_5 = 0;
SET NEW.stoptime = dt;
END IF
$$
DELIMITER ;
I get the error
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 '' at line 8
Got it fixed. Was literally missing the END statement. facepalm
DELIMITER $$
CREATE TRIGGER downinsert BEFORE INSERT ON filleradown
FOR EACH ROW
BEGIN
DECLARE dt DATETIME;
IF NEW.B3_4_5 = '1' THEN
SELECT MAX(time) INTO dt FROM filleradown WHERE filleradown.B3_4_5 = 0;
SET NEW.stoptime = dt;
END IF;
END $$
DELIMITER ;

Avoid firing trigger by another trigger in MYSQL

my problem is as follows:
Table A contains list of "Tasks"
Table B contains "TaskProgress" - just an information about time spent on task, user ID, task ID and note
On table A (Tasks), I have trigger, which updates datetime of last change - column DateChanged (intended to capture datetime of edits made by user)
On table B (TaskProgress) I have trigger, which updates total time spent on a task (sum all times for given Task_ID and update column TotalTime in table A)
I wish to update DateChanged in Table A only when user mades the update (which is every time except when trigger on table B updates TotalTime)
So I wonder, whether there is a way how to tell the database not to fire TRIGGER when updating the values in another trigger.
/* set date of last change and date od closing of task */
DELIMITER $$
CREATE TRIGGER before_tasks_update
BEFORE UPDATE ON tasks
FOR EACH ROW BEGIN
SET new.DateChanged = NOW();
IF new.Status_ID = 3 THEN
SET new.DateClosed = NOW();
END IF;
END$$
DELIMITER ;
/* set total time spent on task */
DELIMITER $$
CREATE TRIGGER after_taskprogress_insert
AFTER INSERT ON taskprogress
FOR EACH ROW BEGIN
DECLARE sumtime TIME;
SET #sumtime := (SELECT SEC_TO_TIME( SUM( TIME_TO_SEC( `timeSpent` ) ) )
FROM taskprogress WHERE Task_ID = new.Task_ID);
UPDATE `tasks` SET TimeReal = #sumtime WHERE ID = new.Task_ID;
END $$
DELIMITER ;
I use MySQL 5.5.40
Thanks, zbynek
Add a check to verify that the update implies a new TimeReal value,since only the second trigger updates that column.
DELIMITER $$
CREATE TRIGGER before_tasks_update
BEFORE UPDATE ON tasks
FOR EACH ROW BEGIN
IF new.TimeReal=old.TimeReal THEN SET new.DateChanged = NOW();
END IF;
IF new.TimeReal=old.TimeReal AND new.Status_ID = 3 THEN
SET new.DateClosed = NOW();
END IF;
END$$
DELIMITER ;

What is wrong with this MySQL Trigger that prevents null dates?

I am trying to create this trigger to prevent insertion of null dates:
CREATE TRIGGER responses_before_insert BEFORE INSERT ON responses
FOR EACH ROW
BEGIN
IF (NEW.date_of_plan IS NULL OR NEW.date_of_plan = '0000-00-00') THEN
SET NEW.date_of_plan = CURDATE();
END IF;
IF (NEW.date_of_update IS NULL OR NEW.date_of_update = '0000-00-00') THEN
SET NEW.date_of_update = CURDATE();
END IF;
END
However, I get the following 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
Can anyone explain what is wrong?
Thanks!
The issue was resolved by changing the delimiter before the query, ie. I executed
DELIMITER $$
Before the trigger query.
Like you did, you need a delimiter.
DELIMITER $$
CREATE TRIGGER responses_before_insert BEFORE INSERT ON responses
FOR EACH ROW
BEGIN
IF (NEW.date_of_plan IS NULL OR NEW.date_of_plan = '0000-00-00') THEN
SET NEW.date_of_plan = CURDATE();
END IF;
IF (NEW.date_of_update IS NULL OR NEW.date_of_update = '0000-00-00') THEN
SET NEW.date_of_update = CURDATE();
END IF;
END $$
DELIMITER ;
Then you can also set it back as done on the last line. Better practie!

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