Trigger after insert doesn't fire for each row - mysql

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.

Related

Mysql On trigger each row

i need help for the below code. My problem is that i want only that code executes once per statement (after i search i checked that expression don't exists anymore only once per row).
So i tried to add:
IF NOT EXISTS
(Select count(*) FROM replay_replays_access WHERE id_game = new.id_game GROUP BY id_game HAVING count(*) <5)
THEN
But didn't work either what can i do, its duplicating sometime triplicating the information?
TRIGGER replay
AFTER UPDATE
ON table_replays FOR EACH ROW
begin
IF EXISTS
(SELECT
replay_games.room_name
FROM replay_games
WHERE replay_games.room_name = 'Tournament Room' and replay_games.id = new.id_game)
THEN
IF NOT EXISTS
(Select
count(*)
FROM replay_replays_access
WHERE id_game = new.id_game
GROUP BY id_game
HAVING count(*) <5)
THEN
INSERT INTO replay_replays_access(id_game, id_player, replay_name, do_not_hide)
SELECT
new.id_game,
replay_users.id ,
CONCAT(
(SELECT game_types
FROM replay_games
WHERE id=new.id_game),
': ',
(SELECT
descr
FROM replay_games
WHERE id=new.id_game)) ,
0
FROM replay_users
WHERE
(replay_users.admin > 0 OR
replay_users.privlevel = 'TOURNAMENT MEMBER')
AND NOT replay_users.name = (
SELECT
replay_games.creator_name
FROM replay_games
WHERE replay_games.id = new.id_game);
END IF;
END IF;
END

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

SELECT CASE statement in TRIGGER

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 ;