I have a table "Comments" and a copy of it, call #Comments_copy (surprise!).
The table "comments" is linked to another one call #article" by a foreigner key as: comments.article_id = article.id.
In Comments_copy: I have a column COUNT(Comments_id).
I try to create a trigger AFTER INSERT into comments which will update the count in comments_copy.
I JUST begin in MySQL so I'm a bit lost in my code.
I guess my problem comes from my condition "WHERE". But I feel clueless to find out the right condition... :(
CREATE TABLE Comments_copy
SELECT Comments.id as C_id, article.id, COUNT(Comments.id) as Nb_comments
FROM Comments
RIGHT JOIN Article ON article.id = Comments.article_id
GROUP BY Article.id
ORDER BY Article.id ;
DELIMITER |
CREATE TRIGGER after_insert_comments AFTER INSERT
ON comments FOR EACH ROW
BEGIN
UPDATE Comments_copy
SET Nb_comments = Nb_comments +1
WHERE id = NEW.id ;
END |
DELIMITER ;
At the end, I expect to recalculate the count of comments JUST for the article concerned by the last comments entry.
Please try in this way.
Please notice that I changed END | to END; |
CREATE TRIGGER after_insert_comments
AFTER INSERT ON comments
FOR EACH ROW
BEGIN
UPDATE Comments_copy
SET Nb_comments = Nb_comments +1
WHERE id = NEW.id ;
END; |
Related
I have an error in my After Update Trigger. I can't figure out where I went wrong. Do you have any suggestions? The trigger is supposed to change the status of another related table (users) when I change the main table I applied my trigger (sites)
CREATE DEFINER=`root`#`localhost` TRIGGER `update_sites_contacts` AFTER UPDATE ON `sites`
FOR EACH ROW
IF NEW.is_mlgu_handled = 1 AND OLD.is_mlgu_handled != NEW.is_mlgu_handled THEN
UPDATE commons_db.users
SET commons_db.users.status = 0
WHERE user_id in (
SELECT user_id FROM
commons_db.sites
LEFT JOIN commons_db.user_organizations using (site_id)
LEFT JOIN commons_db.users using (user_id)
WHERE ewi_recipient = 1
AND org_name in ('lewc','blgu','mlgu')
);
END IF;
Compound statements such as IF...THEN...END IF can only be used inside a BEGIN...END block.
So I do have a problem of understanding here. I would really appreciate if you help to clear my confusion.
So i have 2 tables table_1 and table_2 , where both the tables have the same columns as 'id' pk auto increment and 'name' varchar(20) .
Lets say i already have an after insert trigger on table_1 where everything i insert something in table_1 it stores the same copy in table_2 as well.
Now i wanted to apply an update trigger on the same table (table_1) to control if someone tries to modify the name in table_1 , it should take the name from table_2 and insert the correct name back to table_1.
I hope i explained it well. I will share the after update trigger i made which did not work. I would be more than happy if you help. Thank u
delimiter $$
CREATE TRIGGER `Practice`.`table_1_after_UPDATE` AFTER UPDATE ON `table_1` FOR EACH ROW
BEGIN
if old.name != new.name then
update table_1
set name = table_2.name
where id = table_2.id;
end if;
END$$
delimiter ;
CREATE TRIGGER `Practice`.`table_1_BEFORE_UPDATE`
BEFORE UPDATE
ON `table_1`
FOR EACH ROW
set NEW.name = OLD.name;
I'm trying to make a trigger that will update a column whenever there is an insert on another table. In my case, whenever I insert a new like in the table student_likes_post, I want the table forum_post to update its likes column accordingly. This is my query:
use mydb;
DELIMITER //
CREATE TRIGGER update_likes
after INSERT
ON student_likes_post FOR EACH ROW
BEGIN
UPDATE forum_post
SET forum_post.likes = (
select count(*)
FROM student_likes_post
WHERE student_likes_post.post_id = forum_post.id
);
END;
DELIMITER;
However, when I run it, it just keeps running forever, nothing is happening. The subquery is working though individually. I tried other triggers on the same table student_likes_post that have the same issue. Any idea how I can get this to work? Do you think is a problem with the table itself or with the code?
You probably want to update only the row in forum_post for the post that the student liked, not all the forum_posts, right?
Your trigger is currently updating all the rows in forum_post, and running the subquery once for each row in forum_post.
Here's another way to write the trigger, that updates only the single respective forum_post row:
CREATE TRIGGER update_likes
after INSERT
ON student_likes_post FOR EACH ROW
BEGIN
DECLARE like_count INT;
SELECT COUNT(*) INTO like_count
FROM student_likes_post WHERE post_id = NEW.post_id;
UPDATE forum_post
SET likes = like_count
WHERE id = NEW.post_id;
END
After trying to create a new trigger in invoices table to UPDATE `invoices` SET invoices.`owes` = (`owes` - `paid`);
I get an error because I already that another trigger in payments that is updating. (see below)
I'm looking to keep the existing trigger below, but how to modify it to also update owes to (owes - paid) in the invoices table.
CREATE TRIGGER `after_payment_update` AFTER UPDATE
ON `payments`
FOR EACH ROW UPDATE `invoices`
SET invoices.`paid` = (SELECT SUM(payments .`payment`)
FROM payments WHERE payments.`invoice` = invoices.`invoice`)
You can't create a second trigger that "triggers" on the same action as another trigger. Instead you would use a DELIMITER $$ statement like below and fill your trigger with all the relevant code you want executed.
DELIMITER $$
CREATE TRIGGER after_update_payments
AFTER UPDATE ON payments
FOR EACH ROW BEGIN
UPDATE invoices
SET NEW.paid = (SELECT SUM(payment) FROM payments WHERE invoice = NEW.invoice),
NEW.owes = (owes -(SELECT SUM(payment) FROM payments WHERE invoice = NEW.invoice));
END $$
DELIMITER ;
You don't actually need a DELIMITER in the trigger above, so I will show you an example where you would need to use it:
DELIMITER $$
CREATE TRIGGER after_update_payments
AFTER UPDATE ON payments
FOR EACH ROW BEGIN
IF (some condition here) THEN
UPDATE invoices
SET NEW.paid = (SELECT SUM(payment) FROM payments WHERE invoice = NEW.invoice),
NEW.owes = (owes -(SELECT SUM(payment) FROM payments WHERE invoice = NEW.invoice));
END IF;
END $$
DELIMITER ;
As a general rule, if you need to execute multiple statements that need a ; at the end of them, you need to use a DELIMITER. If this still doesn't make sense, a great explanation for delimiters can be found here.
Now, on a side-note, I don't think this approach is the most optimal one. What I would do in your situation is create a view that combines these tables. For example:
CREATE
ALGORITHM = UNDEFINED
DEFINER = `root`#`localhost`
SQL SECURITY DEFINER
VIEW invoice_payments_view AS (
SELECT
t1.*,
SUM(t2.payment) as amount_paid,
SUM(t2.owes - SUM(t2.payment)) as amount_owed
FROM invoices t1
JOIN payments t2 ON (t1.invoice=t2.invoice)
GROUP BY t1.invoice
)
Then to access the amount_paid and amount_owed columns, you would simply query the following:
SELECT invoice, amount_paid, amount_owed FROM invoice_payments_view
WHERE invoice=1;
Note that I am by no means an expert on this topic, and I am only showing you how I would approach this situation. Also, I didn't test any of this code, so you might need to modify it slightly. If you have any issues let me know and I can update.
I need some help on creating a trigger on MySQL.
I have a table "comment":
id_comment | id_topic | comment
and the "topic" table:
id_topic | topic | comments_ammount
I need to increase comments_ammount for each insert on "comment" table which has the same id_topic of the topic.
I never used triggers, so anyone can help me?
well ,i am not special in mysql but i think you can do something like this
DELIMITER $$
declare #x table(id_topic int)
insert into #x '#x hold last insert'
select *
from comment
order by id desc
limit 1
update topic t join #x c
on c.id_topic =t.id_topic
set comments_ammount=comments_ammount+1
DELIMITER $$
DELIMITER ;