How to fix AFTER UPDATE Trigger - mysql

I created a User Point system for my website. The table looks like this:
user_id name article gallery description total
------------------------------------------------------------
1 joe 7 3 0 10
2 hary 3 5 5 13
3 ana 1 1 2 4
I need an AFTER UPDATE trigger that will make the update SUM in the column total when the value changes in the column, article, gallery or description
DELIMITER $$
CREATE TRIGGER total_trg
AFTER UPDATE point_system FOR EACH ROW
BEGIN
UPDATE point_system SET total = (article + gallery + description) FROM point_system WHERE user_id = NEW.user_id;
END
$$
DELIMITER ;
This trigger does not work. Why?

You cannot modify a table's contents from a trigger on that table (except for the row the trigger is operating on, but not in that way); in this case, what you need is a BEFORE UPDATE trigger, in which you would just
SET NEW.total = NEW.article + NEW.gallery + NEW.description;
You use NEW and OLD to access (and modify in BEFORE triggers) the field values of the row responsible for the trigger firing.

Related

Mysql triggers to copy data from one table to other when a value is inserted

I would like to do a trigger for when a user edit their profile (profile_data) adding the country on the field "Value" that value will be written on player_profile on the flag field and add a .gif at the end. The uid2 value goes to the uid2 flag
profile_data
ID uid Value
1 2 uk
2 1 esp
player_profile
uid flag
1 uk.gif
2 esp.gif
I'm trying to do something like this:
CREATE TRIGGER after_user_insert AFTER INSERT ON profile_data
FOR EACH ROW
BEGIN
INSERT INTO player_profile (flag)
But I don't know what to write more

How to automatically update table when values are added in SQL

I have a table:
vacation_days:
id name work_days hire
-------------------------------------
1 John 369 20151226
2 Mike 767 20141123
3 Josh 1166 20131020
There is a formula to get hire:
UPDATE vacation_days SET work_days = DATEDIFF(CURDATE(),DATE(hire))
However if I add a new row I get null values:
id name work_days hire
-------------------------------------
1 John 369 20151226
2 Mike 767 20141123
3 Josh 1166 20131020
4 Richard NULL 20120623
I have tried to use a trigger like so:
CREATE TRIGGER onInsert BEFORE INSERT ON vacation_days
FOR EACH ROW
BEGIN
SET NEW.work_days = DATEDIFF(CURDATE(),DATE(hire))
END;
However I get an error:
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
''vacation_days' FOR EACH ROW SET work_days = DATEDIFF(CURDATE(), DATE
(NEW.hire))' at line 1
Don't update! Just use a view:
create view v_vacation_days
select vd.*, DATEDIFF(CURDATE(), DATE(vd.hire)) as workdays
from vacation_days vd;
Then the value will be up-to-date whenever you query the view.
Note: You need to remove workdays from the table definition.
Here you are using Insert Before, But the Hire data is not available until inserted, so you can not get the Hire date for the calculations. You want to indicate NEW or OLD Hire data for the usage.
Use this following Insert Before Trigger for your usage,
DELIMITER //
CREATE TRIGGER vacation_days_before_insert
BEFORE INSERT
ON vacation_days FOR EACH ROW
BEGIN
-- Insert record into table
INSERT INTO vacation_days
( id,
name,
work_days,
hire)
VALUES
( NEW.id,
NEW.name,
DATEDIFF(CURDATE(),DATE(NEW.hire)),
NEW.hire );
END; //
DELIMITER ;

add a column to a table with 4 possible default value based on logical argument

How can I add a column to a table with the number 1 to 4 based on each row meeting certain criteria?
Suppose I have a table:
Like this
with two columns (ID) and (RESULTS) and that I want to add a third column called (SCORE).
I want to give a score (between 1 and 4) to each row in my column based on whether the numbers in column (RESULTS) meet certain criteria.
If the RESULT is negative, I want to give it a score of 1,
If the RESULT is less than 30, a score of 2,
less than 100 a score of 3
and greater than 100 a score of 4
I have tried using the CASE statement but cannot seem to get it to work;
I searched on the topics about constraints but they always seem to have two arguments - I need 4
I have updated the answer, as more details were given in the question (and to fix some errors)
Please remember to change table_name and trigger_name to appropriate names :).
SOLUTION:
You should first of all add the third column to the table
ALTER TABLE table_name ADD COLUMN SCORE INT;
You should add the trigger to set the SCORE for the new rows:
DELIMITER $$
CREATE TRIGGER trigger_name BEFORE INSERT ON table_name
FOR EACH ROW
BEGIN
SET NEW.SCORE = CASE WHEN NEW.RESULTS < 0 THEN 1 WHEN NEW.RESULTS < 30 THEN 2 WHEN NEW.RESULTS < 100 THEN 3 ELSE 4 END;
END$$
DELIMITER ;
And you should initialize SCORE values for rows existing in the table
UPDATE table_name t
SET t.SCORE = CASE WHEN t.RESULTS < 0 THEN 1 WHEN t.RESULTS < 30 THEN 2 WHEN t.RESULTS < 100 THEN 3 ELSE 4 END;
Hope it helps.

MySQL trigger to create timer

There is a special data type 'time' in MySQL.
How would a trigger look if I want my 'time' value to start counting when some state_id changes from 1 to 2? For example:
CREATE TRIGGER log_time AFTER UPDATE ON usr
FOR EACH ROW
BEGIN
IF usr.st_id = 2 THEN
#.... - thats what i dont know
END IF;
END;
It would stop counting when the state_id changes back from 2 to 1.
Instead of starting/stopping the counter (I don't know if that's even possible), you should store the value in 2 different columns (and then substract to get the time when needed)
DELIMITER $$
CREATE TRIGGER log_time AFTER UPDATE ON usr
FOR EACH ROW
BEGIN
IF new.st_id = 2 THEN
UPDATE <table> set <log_start_time> = CURTIME() <where_clause>;
elseif new.st_id = 1 THEN
UPDATE <table> set <log_end_time> = CURTIME() <where_clause>;
END IF;
END;
$$
DELIMITER;
OR in 1 column by storing initial value and then updating it in the trigger
DELIMITER $$
CREATE TRIGGER log_time AFTER UPDATE ON usr
FOR EACH ROW
BEGIN
IF new.st_id = 2 THEN
UPDATE <table> set <logtime> = CURTIME() <where_clause>;
else if new.st_id = 1 THEN
UPDATE <table> set <logtime> = subtime(CURTIME(), select statement to get original value) <where_clause>;
END IF;
END;
$$
DELIMITER;
Okay I'm new to coding and was wondering if this would even be possible and if so what would be the best way to get around this problem
Okay in my database I have a row for current time and a row for duration and I am wanting to find a way so that when the time is the value of T + D it would change a colour (green) ? Or even better if it could be done so if equal to or under 2 mins amber colour and over 2 mins red colour ( kind of like a traffic light idea)
Hope this makes sense
T | D
---------------
22:50 | 6 (mins)
At 22:56 this would change colour on website
Thank You

deactivate if date expired trigger

i want to be able to update the filed 'activated' to 0 when the 'expireDate' is before today.
can you show me how to do it with a triger? (i want to do this after the user insert the row)
id expireDate activated
1 2011-11-21 1
2 2011-04-22 1
It will look something like this (tested on MySQL 5.1.37):
CREATE TRIGGER my_trigger
BEFORE INSERT ON activity
FOR EACH ROW
IF NEW.deadline < CURDATE() THEN
SET NEW.activity = 0;
END IF