mysql stored procedure not firing from event scheduler - mysql

Can someone please tell me what's wrong with this sp. The logic seems to be ok, but when i check back in my table it doesn't work at all.
DELIMITER //
DROP PROCEDURE IF EXISTS add_zero_yearly_sales_proc //
CREATE PROCEDURE add_zero_yearly_sales_proc()
READS SQL DATA
BEGIN
DECLARE num_of_sales INT DEFAULT 0;
DECLARE last_ins_date DATETIME;
DECLARE done INT DEFAULT 0;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
SET last_ins_date = DATE_SUB(NOW(), INTERVAL 2 YEAR);
ins_loop: WHILE last_ins_date < NOW() DO
SELECT COUNT(sales_amount_sold) INTO num_of_sales
FROM yearly_sales
WHERE sales_date_sold BETWEEN DATE_FORMAT(last_ins_date,'%Y-%m-01 00:00:01') AND DATE_FORMAT(LAST_DAY(last_ins_date),'%Y-%m-%d 23:59:59');
IF num_of_sales = 0 THEN
INSERT INTO yearly_sales(sales_date_sold, sales_amount_sold,sales_quantity)
VALUES (CONCAT(DATE_FORMAT(last_ins_date,'%Y-%m-01 00:00:01')),0, 0);
END IF ;
SET num_of_sales = 0;
SET last_ins_date = DATE_ADD(last_ins_date, INTERVAL 1 MONTH);
END WHILE ins_loop;
SET done = 0;
END ;//
DELIMITER ;
I've created an event that fires every hour to call this procedure. The procedure is supposed to check if there are months in the yearly_sales table without any sales values in them, and if so add 0 values for the amount & quantity, and the beginning of the month for the date. I've checked back but it doesn't seem to work.
Also here's the event i created to call it hourly
DELIMITER //
CREATE
EVENT `hourly_sales_evt`
ON SCHEDULE EVERY 1 HOUR STARTS DATE_FORMAT(NOW(),'%Y-%m-%d %H:55:00')
ON COMPLETION PRESERVE
DO BEGIN
CALL add_zero_yearly_sales_proc();
END //
DELIMITER ;

May be global event scheduler is in stopped/disabled state.
To turn on event scheduler, run any of the following:
SET GLOBAL event_scheduler = ON;
SET ##global.event_scheduler = ON;
SET GLOBAL event_scheduler = 1;
SET ##global.event_scheduler = 1;
When the Event Scheduler is ON, the event scheduler thread is listed in the output of SHOW PROCESSLIST as a daemon process, and its state is represented as shown here:
mysql> SHOW PROCESSLIST\G
*************************** 1. row ***************************
Id: 1
User: root
Host: localhost
db: NULL
Command: Query
Time: 0
State: NULL
Info: show processlist
*************************** 2. row ***************************
Id: 2
User: event_scheduler
Host: localhost
db: NULL
Command: Daemon
Time: 3
State: Waiting for next activation
Info: NULL
2 rows in set (0.00 sec)
Once the Event Scheduler is set ON, you would see it working.
Refer to : MySQL Event Scheduler Configuration

The procedure looks OK, the logic should work. But, I want to ask you - why do you check sales_date_sold from first second -DATE_FORMAT(last_ins_date,'%Y-%m-01 00:00:01'), shouldn't it be DATE_FORMAT(last_ins_date,'%Y-%m-01 00:00:00')?
Another point: you execute SELECT statement many times in the loop, it is not effective. Try to create additional (maybe temporary table) with month numbers and join two tables to find out months without any sales. In this case you will achieve result in one step.

I'm taking a guess here without doing much digging, but I think this is your issue:
READS SQL DATA
...
INSERT INTO yearly_sales(sales_date_sold, sales_amount_sold,sales_quantity)
VALUES (CONCAT(DATE_FORMAT(last_ins_date,'%Y-%m-01 00:00:01')),0, 0);

Related

SQL Event - DELETE AND UPDATE rows on tables after UPDATE other table

I'd like to have a tricky SQL statement as an Event that runs every couple of minutes.
Currently, I'm doing so with Java, using 3 separate statements that executing sequentiality in a transaction connection.
Q: I don't know how to construct such an SQL statement without Java. If impossible to have a single SQL statement, I'd like to use transaction (as I'm using in Java) and rollback in case of failure in any of those separate statements.
My Case:
I have 3 tables: "Factory", "Plan", "Machine".
I want to do something as below:
1.
WHERE Machines.annualCheck == "TRUE"
SET Machine.status = "IN_ANNUAL_CHECK"
For machines that got updated I need to do the following:
2.1 Update the related factory
WHERE Factory.id == Machine.linkFactoryID
UPDATE Factory.totalActiveMachines = --1
2.2 Delete the upcoming plans that planned to be handled by the related machine
DELETE rows WHERE Plan.willHandleByMachineID = Machine.ID
p.s. I'm using MySQL
Thank you!
Update:
In following to Simonare suggestion, I tired to do the following:
DELIMITER $
CREATE PROCEDURE annualCheck(IN Machine_ID int, IN Factory_ID int)
BEGIN
UPDATE machine_table
SET machine_table.annualCheck = 'IN_ANNUAL_CHECK'
WHERE machine_table.machine_id = Machine_ID;
UPDATE factory_table
SET factory_table.totalActiveMachines = factory_table.totalActiveMachines - 1
WHERE factory_table.factory_id = Factory_ID;
DELETE FROM plan_table WHERE plan_table.assign_to_machine = Machine_ID
END$
DELIMITER $$
BEGIN
SELECT #m_id = machine_id, #f_id = link_factory_id
FROM machine_table
WHERE machine_table.annualCheck = 'TRUE';
END$$
CALL annualCheck(#m_id,#f_id)
I don't know why, but I'm running into syntax errors - one after the other.
It's my first time to use PROCEDURE and DELIMITER. Am I doing it right?
you can use stored procedure
delimiter //
CREATE PROCEDURE myProc (IN Machine_ID int)
BEGIN
UPDATE myTable
SET Machine.status = "IN_ANNUAL_CHECK"
WHERE Machines.annualCheck == "TRUE";
Update the related factory
WHERE Factory.id == Machine.linkFactoryID
UPDATE Factory.totalActiveMachines = totalActiveMachines -1;
DELETE FROM Plan WHERE Plan.willHandleByMachineID = Machine_ID;
END//
then you can execute it either from mysql
CALL simpleproc(#a);
or from Java
It is also possible to create trigger on the Machine table, something like this:
CREATE TRIGGER `TRG_Machines_AfterUpdate` AFTER UPDATE ON `Machine` FOR EACH ROW BEGIN
IF OLD.annualCheck = 'TRUE' AND NEW.annualCheck = 'IN_ANNUAL_CHECK' THEN
UPDATE
Factory
SET
totalActiveMachines = totalActiveMachines - 1
WHERE
id = NEW.linkFactoryID
;
DELETE FROM
Plan
WHERE
willHandleByMachineID = NEW.ID
;
END;
END
So you can just issue normal update:
UPDATE Machine SET annualCheck = 'IN_ANNUAL_CHECK' WHERE annualCheck = 'TRUE'

Why is this mysql trigger syntax is wrong?

There are two tables involved in this question: Register(eid, sid, price, rating) and Event (eid, ename, edescription, edate, memprice, nonmemprice, maxpeople).
I want to create a trigger that is monitoring the Register that if the number of registrations of any Event exceed the 80% of the maximum people allowed in such event, we arise the non-memberprice of this event by 50%.
So far I have something like this
delimiter//
create trigger price_change
after insert on Register for each row begin
DECLARE counts INT;
DECLARE maxpeople INT;
set counts = (select count(sid) from Register
JOIN Event ON Register.eid = Event.eid
where eid = new.eid);
set maxpeople = (select maxpeople from Event where Event.eid =
new.eid);
if counts >= 0.8 * maxpeople
then
update Event set nonmemprice = nonmemprice * 1.5 where eid
= new.eid;
end if;
end//
delimiter;
I'm still learning how to write trigger and I ended up with this trigger. I tried to add it into MySQL but it said there are syntax errors basically everywhere of this trigger. I'm really confused. It would be appreciated if anyone help me with this.
The error is right at the beginning. Use a space in between:
delimiter //
^--------------here
And at the end of course too: delimiter ;

MySQL events doesn't run eventhough every settings is enable

I have created simple event but it doesn't run:
DELIMITER |
CREATE EVENT myevent3
ON SCHEDULE EVERY 1 second
STARTS current_timestamp()
ENDS CURRENT_TIMESTAMP + INTERVAL 1 DAY
DO
BEGIN
UPDATE hiberante.animal SET name = name + 'a' where id = 6;
END |
DELIMITER ;
I have done:
SET GLOBAL event_scheduler = ON;
Also done:
SELECT * FROM INFORMATION_SCHEMA.EVENTS;
and
SELECT * FROM mysql.event;
And it still doesn't want to start working.
In my process list:
SHOW PROCESSLIST;

Mysql Event Scheduler : Table Does not exist error , despite existing

Looking for some advice please :
I have a MySQL 5.6 Event scheduler set up as below:
DELIMITER $$
CREATE DEFINER=`root`#`10.0.0.%` EVENT `update_reports` ON SCHEDULE EVERY 3 MINUTE STARTS '2015-10-16 13:01:20' ON COMPLETION PRESERVE ENABLE DO update_reports:BEGIN
DECLARE triggered datetime DEFAULT SYSDATE();
DECLARE started datetime DEFAULT NULL;
DECLARE status tinyint(1) DEFAULT 0;
# LOGIC
IF wait_for_processing('reports.processing') THEN
SET started = SYSDATE();
# SET SESSION VARIABLES
SELECT enable_logging(false);
SELECT enable_debug_timers(true);
SET #reporting_from = '2013-03-01 00:00:00';
IF (needs_update()) THEN
SELECT update_usage_data();
SET status = 1;
ELSE
SET status = 2;
END IF;
SELECT free_for_processing('reports.processing');
END IF;
INSERT INTO ref.event_logs
SELECT
'reports',
'update_reports',
triggered,
started,
SYSDATE(),
null,
status;
END update_reports
However, in the MySql Error log I am receiving this error:
2015-10-16 13:37:20 29327 [ERROR] Event Scheduler: [root#10.0.0.%][reports.update_reports] Table 'reports.reporting_statsevent_logsuser_seen' doesn't exist
2015-10-16 13:37:20 29327 [Note] Event Scheduler: [root#10.0.0.%].[reports.update_reports] event execution failed.
Permissions on the database and tables show root#10.0.0.% to have full permissions.
Could anyone please share any troubleshooting steps I can take to understand why the event scheduler cannot access the tables, yet the queries work fine when carried out in MySql Workbench.
Thank you.

MYSQL - check a time and execute query

I'd like (if it possible) check a time and if time = special time, make update of the table.
My idea:
select current_time()
if current_time = 15:19
{
update tasks set finished = replace (finished, '1', '0')
}
Do you have any ideas???
Use an event for that
delimiter //
CREATE EVENT IF NOT EXISTS your_event
ON SCHEDULE EVERY 1 DAY
STARTS '2014-07-04 15:19:00'
ON COMPLETION PRESERVE ENABLE
DO
update tasks
set finished = replace (finished, '1', '0');
//
It will be executed automatically every day on the defined time.