Trigger firing on every update instead of just one column - mysql

I have a trigger in MySQL table. Table has about 20 columns.
DELIMITER $$
CREATE
DEFINER=`root`#`localhost`
TRIGGER `completion_date_update`
BEFORE UPDATE ON `orders`
FOR EACH ROW
BEGIN
IF NEW.`order_status` = 'COMPLETED' THEN
SET NEW.`completion_date` = NOW();
END IF;
IF NEW.`order_status` != 'COMPLETED' THEN
SET NEW.`completion_date` = NULL;
END IF;
END$$
What I want is this trigger to update completion_date column only when column order_status is updated. If any other column is updated this trigger should not do anything.
What is actually happening is this trigger is updating completion_date upon any column update.
Can anyone explain to me why does this happen and what did I do wrong?
order_status column is NOT NULL and has possible values as below:
enum('NEW','OPEN','COMPLETED','CANCELLED','REPLACED')
Default is 'NEW'
Thanks

you should also compare if order_status has been changed and that the new value is COMPLETED
IF (NEW.order_status <> OLD.order_status) AND (NEW.order_status = 'COMPLETED') THEN
SET NEW.completion_date = NOW();
END IF;
and you can remove the other IF below.

Related

Update one mysql column when another is edited

I'm trying to make a datetime field that automatically gets updated with the current time only if there was a change to a certain field.
It seems I have a syntax error.
CREATE OR ALTER TRIGGER last_progress_date
ON wp_task_mgr
AFTER UPDATE
AS BEGIN
IF UPDATE (progress_percentage)
SET last_progress_date = GETDATE()
END
Just for future reference, I found the answer here:
https://dba.stackexchange.com/questions/125203/simple-trigger-to-update-two-columns-in-one-table
MySQL query:
DELIMITER //
CREATE TRIGGER trig_1 before insert
ON <table_name> FOR EACH ROW
BEGIN
IF new.due_date is not null and new.end_date='' then
set new.end_date=new.due_date;
end if;
IF new.end_date is not null and new.due_date='' then
set new.due_date=new.end_date;
end if;
END;
//
DELIMITER //
CREATE TRIGGER trig_2 before update
ON <table_name> FOR EACH ROW
BEGIN
IF new.due_date <>old.due_date then
set new.end_date=new.due_date;
end if;
IF new.end_date <> old.end_date then
set new.due_date=new.end_date;
end if;
END;
//

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 ;

MySQL ON UPDATE trigger - update the same table with CURRENT_TIMESTAMP and condition

I have a MySQL(5.1.67) table 'tracker' with TIMESTAMP field 'close_time'.
In the same table I have string field 'status'.
I want to update close_time field with CURRENT_TIMESTAMP value when status field updated to specific text value, for example 'Closed'.
Here is sample with INSERT:
How can I write a trigger that updates rows in the same table, before the insert is commited?
I tried something like that:
CREATE TRIGGER `close_time_trigger` BEFORE UPDATE ON `tracker` FOR EACH ROW
BEGIN
IF NEW.status = 'Closed' THEN
SET NEW.close_time = CURRENT_TIMESTAMP;
END IF;
END
But I got error: You have an error in your SQL syntax ... at line 4.
I tried some other variations which I found but none of them works.
Please help to create correct trigger for my case.
Did you set the DELIMITER?
This should work:
DELIMITER $$
CREATE TRIGGER `close_time_trigger` BEFORE UPDATE ON `tracker` FOR EACH ROW
BEGIN
IF NEW.status = 'Closed' THEN
SET NEW.close_time = CURRENT_TIMESTAMP;
END IF;
END $$
DELIMITER ;
you didn't tell it what to update.
CREATE TRIGGER `close_time_trigger` BEFORE UPDATE ON `tracker` FOR EACH ROW
BEGIN
IF NEW.status = 'Closed' THEN
update tracker
SET NEW.close_time = CURRENT_TIMESTAMP;
END IF;
END

MSQL Error 1193--updating on the same table

I'm trying to create a trigger to update a column in the same table after another update. I am given a SQL Error (1193): Unknown system variable
I thought this is fairly straightforward, but it doesn't seem to like it very much. Please help!
CREATE TRIGGER `redeem_gc`
BEFORE UPDATE ON `giftcards`
FOR EACH ROW
IF NEW.value = 0 THEN
SET `status`= '2'
END IF
what the code should do is if the value reaches 0, then update the status to 'x'
Thanks.
delimiter |
CREATE TRIGGER `redeem_gc` BEFORE UPDATE ON `giftcards`
FOR EACH ROW BEGIN
IF NEW.value = 0 THEN
SET NEW.`status`= '2';
END IF;
END
|
delimiter ;

MYSQL Trigger set datetime value using case statement

I'm using mysqlimport to do mass table inserts (replacing duplicates primary keys). Several tables have date time columns with records containing values '0000-00-00'. What I would like is a trigger which detects these '0000-00-00' values and replaces with '1950-01-01', otherwise keep the datetime value in the record (i.e. when it's not '0000-00-00').
I have tried the following:
CREATE TRIGGER set_datetime BEFORE INSERT ON tbl
FOR EACH ROW
CASE
WHEN date_col='0000-00-00' THEN SET date_col='1950-01-01';
END CASE
Thank you.
EDIT
Update attempt:
CREATE TRIGGER set_datetime BEFORE INSERT ON tbl
FOR EACH ROW
IF (NEW.date_col='0000-00-00') THEN
SET NEW.date_col='1950-01-01';
END IF;
Still getting an error in the SET portion.
EDIT 2
WORKING:
DELIMITER $$
CREATE TRIGGER insert_check BEFORE INSERT ON ar
FOR EACH ROW
BEGIN
IF NEW.delivery_date='0000-00-00' THEN
SET NEW.delivery_date='1950-01-01';
END IF;
END; $$
DELIMITER ;
Use IF THEN :
IF (NEW.date_col = '0000-00-00') THEN
SET NEW.date_col='1950-01-01';
END IF;
CREATE TRIGGER set_datetime BEFORE INSERT ON tbl
FOR EACH ROW
IF YEAR(NEW.date_col)=0 THEN
SET NEW.date_col='1950-01-01 00:00:00';
END IF;
Give it a Try !!!
If you want, or need, to use 'case' then this should work:
SET NEW.date_col=CASE WHEN NEW.date_col='0000-00-00' THEN ='1950-01-01'
WHEN NEW.date_col='something else' THEN 'whatever'
ELSE 'default'
END CASE;