SELECT CASE statement in TRIGGER - mysql

I have a query with "SELECT CASE" statement that's working fine:
SELECT
(CASE `t`.`is_combined`
WHEN 0
THEN `t`.`topic_id`
ELSE `t`.`is_combined`
END) AS`group_id`,
SUM(`ctt`.`tm_download_status`) AS `is_downloaded`,
COUNT(`t`.`topic_id`) AS `group_topics_cnt`,
(SUM(`ctt`.`tm_download_status`) = COUNT(`t`.`topic_id`)) AS `is_downloaded_group`
FROM (`catalog_topics` `t` LEFT JOIN `catalog_tracker_torrents` `ctt` ON((`ctt`.`topic_id` = `t`.`topic_id`)))
WHERE (`t`.`topic_id` != 0)
GROUP BY (`group_id`)
So, i want to create a similar trigger to update "cross" table:
DELIMITER $$
CREATE TRIGGER `tdg_ins_by_topics` AFTER INSERT ON `catalog_topics` FOR EACH ROW
BEGIN
REPLACE INTO catalog_topics_downloaded_groups(
SELECT (
CASE `t`.`is_combined`
WHEN 0
THEN `t`.`topic_id`
ELSE `t`.`is_combined`
END
) AS `group_id` ,
SUM( `ctt`.`tm_download_status` ) AS `is_downloaded` ,
COUNT( `t`.`topic_id` ) AS `group_topics_cnt` , (
SUM( `ctt`.`tm_download_status` ) = COUNT( `t`.`topic_id` ) ) AS `is_downloaded_group`
FROM `catalog_topics` `t`
LEFT JOIN `catalog_tracker_torrents` `ctt` ON `ctt`.`topic_id` = `t`.`topic_id`
WHERE `t`.`topic_id`
IN (
NEW.`topic_id`
)
GROUP BY `group_id`
)
END ;
$$
But getting an error message:
"#"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 'END' at line 14
It's look like that MySQL doesn't understand difference between CASE in TRIGGER statement and CASE in SELECT statement. So, how i can fix this?
Thanks for the answers.

I think you need to "end" your REPLACE statement with ; like you have to end all statements inside a TRIGGER or PROCEDURE/FUNCTION with a delimeter.
That is why you change the DELIMETER to $$ .. so you can use ; to store the mysql default delimeter inside of the trigger code. (and end the create trigger statement with the changed $$ delimeter)
DELIMITER $$
CREATE TRIGGER `tdg_ins_by_topics` AFTER INSERT ON `catalog_topics` FOR EACH ROW
BEGIN
REPLACE INTO catalog_topics_downloaded_groups(
SELECT ( CASE `t`.`is_combined`
WHEN 0
THEN `t`.`topic_id`
ELSE `t`.`is_combined`
END
) AS `group_id`,
SUM(`ctt`.`tm_download_status`) AS `is_downloaded`,
COUNT( `t`.`topic_id` ) AS `group_topics_cnt` ,
(
SUM( `ctt`.`tm_download_status` ) = COUNT( `t`.`topic_id` ) ) AS `is_downloaded_group`
FROM `catalog_topics` `t`
LEFT JOIN `catalog_tracker_torrents` `ctt` ON `ctt`.`topic_id` = `t`.`topic_id`
WHERE `t`.`topic_id` IN ( NEW.`topic_id` )
GROUP BY `group_id`
);
END;
$$
DELIMETER ;

Related

Trigger before insert fire error if there has no data on fetching table.

CREATE TRIGGER `staff_auto_salary` BEFORE INSERT ON `staff_attendance`
FOR EACH ROW BEGIN
IF NEW.att_present LIKE 'P'
THEN
SET NEW.wages = (SELECT staff_emp_salary FROM staff_salary WHERE staff_emp_id = NEW.att_staff_id ) / (SELECT DAY( LAST_DAY( NOW( ) ) ) );
ELSEIF NEW.att_present LIKE 'HALF' THEN SET NEW.wages = ( SELECT staff_emp_salary FROM staff_salary WHERE staff_emp_id = NEW.att_staff_id ) / ( SELECT DAY( LAST_DAY( NOW( ) ) ) ) /2;
END IF ;
END
Above is my trigger code this trigger added wages as per employee salary which are in staff_emp_salary table. Trigger will fire when insert on staff_attendance table and fetch salary from staff_salary if salary is not in table then it will fire error, so i want if there is no salary for employee in staff_emp_salary table then insert 0.
I fond solution as below.
DROP TRIGGER IF EXISTS `staff_auto_salary`;
DELIMITER //
CREATE TRIGGER `staff_auto_salary` BEFORE INSERT ON `staff_attendance`
FOR EACH ROW BEGIN
IF NEW.att_present LIKE 'P'
THEN
SET NEW.wages = (SELECT IF(count(`staff_emp_salary`)!=0,`staff_emp_salary`,'0') as `staff_emp_salary` FROM staff_salary WHERE staff_emp_id = NEW.att_staff_id ) / (SELECT DAY( LAST_DAY( NOW( ) ) ) );
ELSEIF NEW.att_present LIKE 'HALF' THEN SET NEW.wages = ( SELECT IF(count(`staff_emp_salary`)!=0,`staff_emp_salary`,'0') as `staff_emp_salary` FROM staff_salary WHERE staff_emp_id = NEW.att_staff_id ) / ( SELECT DAY( LAST_DAY( NOW( ) ) ) ) /2;
END IF ;
END //
DELIMITER ;

Appending additional SQL tigger to existing trigger

I have the following SQL update trigger that works properly:
BEGIN
DECLARE myID INT;
SELECT user_id INTO myID FROM writer WHERE writer_id = NEW.writer_id;
IF (NEW.status_id = 2) THEN
INSERT INTO activity (
user_id,
work_id,
activity,
date_created
) VALUES (
myID,
NEW.work_id,
'confirmed',
now()
);
ELSE
INSERT INTO activity (
user_id,
work_id,
activity,
date_created
) VALUES (
myID,
NEW.work_id,
'modified',
now()
);
END IF;
END
I need to add an additional trigger as the following:
CREATE TRIGGER updateWorkStatus AFTER UPDATE ON writer_split
FOR EACH ROW
BEGIN
UPDATE work a
JOIN writer_split b
ON a.work_id = b.work_id AND a.current_version = b.version
SET a.status_id = 2
WHERE a.work_id NOT IN (
SELECT ab.work_id
FROM (SELECT s.work_id
FROM work w INNER JOIN writer_split s
ON w.work_id = s.work_id AND s.status_id != 2) ab
);
END;
when I run this create script, I am getting a syntax error. Any ideas?
For me i will use UPDATE work as a

MYSQL Stored Procedures INSERT Fails

I am using MYSQL version 5.5
I am trying to insert the following procedure:
CREATE PROCEDURE `myTestProceed3ure` ( IN _id INT )
IF( SELECT COUNT( * ) FROM `tbl_search_counter` WHERE user_id = u_userid ) >0
THEN
(SELECT COUNT( * ) FROM `tbl_search_counter` WHERE user_id = u_userid);
ELSE
(INSERT INTO `tbl_search_counter` (`user_id` ,`time_searched`) VALUES ('165', '7'));
END IF
But for whatever reason I get the following error message
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 'INSERT INTO tbl_search_counter (user_id ,time_searched)
VALUE' at line 6
I really don't understand because when I do the following request I do not experience problem
CREATE PROCEDURE `myTestProceed2ure` ( IN `_id` INT )
INSERT INTO `tbl_search_counter` (`user_id`, `time_searched`) VALUES ('15', '7')
or the following
CREATE PROCEDURE `myTestProceed3ure` ( IN _id INT )
IF( SELECT COUNT( * ) FROM `tbl_search_counter` WHERE user_id = u_userid ) >0
THEN
(SELECT COUNT( * ) FROM `tbl_search_counter` WHERE user_id = u_userid);
ELSE
(SELECT COUNT( * ) FROM `tbl_search_counter` WHERE user_id = u_userid);
END IF
If someone has any idea what I am doing wrong, let me know...
Thanks
What is your stored procedure supposed to be doing? You are not referencing the parameter to the stored procedure and u_userid seems undefined.
If you just want to insert an id that doesn't currently exist, then here is one way:
CREATE PROCEDURE `myTestProceed3ure` (IN _id INT )
INSERT INTO tbl_search_counter(user_id, time_searched)
VALUES (_id, '7')
ON DUPLICATE KEY UPDATE user_id = values(user_id)
END IF;
Final answer: I should not have put () before the INSERT...
CREATE PROCEDURE `myTestProceed3ure` ( IN _id INT )
IF( SELECT COUNT( * ) FROM `tbl_search_counter` WHERE user_id = u_userid ) >0
THEN
(SELECT COUNT( * ) FROM `tbl_search_counter` WHERE user_id = u_userid);
ELSE
INSERT INTO `tbl_search_counter` (`user_id` ,`time_searched`) VALUES ('165', '7');
END IF

MYSQL trigger syntax error. #1064

delimiter //
CREATE TRIGGER Raiting_added AFTER INSERT ON raiting
FOR EACH ROW
BEGIN
declare del INT;
SET del = (SELECT COUNT( rait_id ) FROM `raiting` WHERE NEW.movie_id AND user = NEW.user);
IF del > 0 THEN
DELETE FROM movies WHERE movie_id = NEW.movie_id AND user = NEW.user
END IF;
UPDATE movies
SET raiting = ( SELECT ROUND( AVG( seted_rait ) , 1 )
FROM `raiting`
WHERE movie_id = NEW.movie_id)
WHERE movie_id = NEW.movie_id
END
delimiter;
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 'END IF; UPDATE movies SET raiting = ( SELECT ROUND( AVG(
seted_rait ) , 1 ) ' at line 10
what is problem? can someone help?
You have forgotten "= movie_id" and few semicolons
delimiter //
CREATE TRIGGER Raiting_added AFTER INSERT ON raiting
FOR EACH ROW
BEGIN
declare del INT;
SET del = (SELECT COUNT( rait_id ) FROM `raiting` WHERE NEW.movie_id AND user = NEW.user);
IF del > 0 THEN
DELETE FROM movies WHERE movie_id = NEW.movie_id AND user = NEW.user;
END IF;
UPDATE movies
SET raiting = ( SELECT ROUND( AVG( seted_rait ) , 1 )
FROM `raiting`
WHERE movie_id = NEW.movie_id)
WHERE movie_id = NEW.movie_id;
END;
//
delimiter ;

Trigger after insert doesn't fire for each row

Hey i have a trigger that fires after update that's defined as following:
CREATE DEFINER = `root`#`localhost` TRIGGER `logs_m` AFTER UPDATE ON
`logs_month` FOR EACH ROW
BEGIN IF NEW.status =1 THEN INSERT INTO logs_payments( direction,
TYPE , amount, agent_id, invoice_number )
VALUES ( 0, 3, NEW.reward_minutes, NEW.agent_id, NULL ) ,
( 0, 5, NEW.credit, NEW.agent_id, NULL ) ;
END IF ;
END
Now on logs_payments i have a trigger on after insert which is defined like this :
CREATE DEFINER = `root`#`localhost` TRIGGER `payments_invoice` BEFORE INSERT ON
`logs_payments`
FOR EACH
ROW BEGIN
IF NEW.direction =0
THEN
SET NEW.invoice_number = ( SELECT MAX( IFNULL( invoice_number, 100000000 ) ) +1
FROM logs_payments l
WHERE l.direction =0 ) ;
END IF ;
IF NEW.direction =1 THEN SET NEW.invoice_number =
( SELECT MAX( IFNULL( invoice_number, 200000000 ) ) +1
FROM logs_payments l
WHERE l.direction =1 ) ;
END IF ;
END
Now the the first inserted row invoice_number gets null and the 2nd gets the right value.
Any idea why that should happen?
Solved it, the triggers where fine I had a problem in my query, since I didn't have value on first I set :
SELECT MAX( IFNULL( invoice_number, 100000000 ) ) +1
Which was wrong it should be
select ifnull(max(invoice_number),100000000)+1
And now it works fine.