ZF2 MYSQL Event Manager Custom Query - mysql

I am trying to save an event in MySQL event Manager with two parts as shown below.
I can add it successfully via PHPMyAdmin, but with ZF2 TAblegateway no joy..
Any solution - directly through php would be acceptable for now..
$this->tableGateway->getAdapter()->driver->getConnection()>execute($eventSql);
$eventSql =
"DELIMITER |
CREATE EVENT slacheckevent9
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 2 MINUTE
DO
BEGIN
UPDATE sla AS T1,
(SELECT eventdata FROM eventdata WHERE eventname = 'CUSTOMER
CONTACTED' AND instructionid=3) AS T2
SET T1.actualtime=T2.eventdata WHERE T1.id = 9;
UPDATE sla
SET slasuccess= CASE
WHEN actualtime <= duetime THEN true
ELSE slasuccess
END
WHERE id = 9
;
END |
DELIMITER ;";

Simply:
$eventSql = "
CREATE EVENT slacheckevent9
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 2 MINUTE
DO
BEGIN
UPDATE sla AS T1,
(SELECT eventdata FROM eventdata WHERE eventname = 'CUSTOMER
CONTACTED' AND instructionid=3) AS T2
SET T1.actualtime=T2.eventdata WHERE T1.id = 9;
UPDATE sla
SET slasuccess= CASE
WHEN actualtime <= duetime THEN true
ELSE slasuccess
END
WHERE id = 9
;
END
";
$this->tableGateway->getAdapter()->query($eventSql, \Zend\Db\Adapter\Adapter::QUERY_MODE_EXECUTE);

Related

Events dynamic value passing

My current snippet has added here.
Problem is while doing an insert into mail table that time I have Triggered Value: lc_calc_value so lc_calc_value should be inserted from select query but it's not going to insert value.
Code :
CREATE EVENT custom_alert ON SCHEDULE EVERY 600 SECOND DO
BEGIN
DECLARE lc_current_time DATETIME;
DECLARE lc_calc_value DECIMAL(8,2);
SET lc_current_time = CONVERT_TZ(NOW(), ##session.time_zone, '+0:00');
SELECT AVG(billseconds) AS calc_value FROM table1 c WHERE c.date > lc_current_time + INTERVAL -600 SECOND AND c.date <= lc_current_time AND group_id = 7 into lc_calc_value ;
IF lc_calc_value <= 10.00 THEN
INSERT INTO custom_report(triggered_value,type,status,email,group_od,threshold_value,period,triggered_date) value (lc_calc_value,2,1,'abc.com',7,10.00,600,lc_current_time);
INSERT INTO mail (`date`,`subject`,`body`,`from`,`to`,`status`,`reseller_id`) VALUES (1,lc_current_time,'Alarm : ACD','Hello Admin,
Name : ACD,
Type : Gateway,
Threshold : 10.00
Period : 100
Trunk/CLI : new_test
Triggered Value : lc_calc_value','abc#ghi.com','abc.com',1,0);
END IF;
Is there already an entry in "custom_report" with the same PK?
Also your insert looks wrong. When I read it, you try to insert:
mail.date = 1
mail.subject = lc_current_time
mail.body = "Alarm...
...
I assume you messed up the query.

How do I create a function / procedure in MariaDB to run an update script when the table got accessed?

I have some records in my DB with a special Status let's say t_status = 'T' and I want to update each t_status which has an t_moddate older than 45 minutes to t_status = 'X'.
How can i put this into a stored procedure in Maria DB?
My table looks like below:
table name: Test
columns: t_id,t_status,t_moddate,t_usr_update
I guess my update is like below:
UPDATE TEST SET t_status = 'X' where t_status = 'T' and t_moddate <= now()- interval(45 minutes);
CREATE PROCEDURE myProc()
BEGIN
UPDATE TEST
SET t_status = REPLACE (first_name, 'T', 'X')
WHERE t_status = 'T' and t_moddate <= now()- interval 45 minute;
END$$
But how do I get this into a stored procedure to let it run by default?
You can use an EVENT run hourly or whatever interval you choose.
First enable it
SET GLOBAL event_scheduler = ON;
Then write the event proper
CREATE EVENT somename
ON SCHEDULE EVERY '1' HOUR
STARTS '2017-25-12 00:00:00'
DO
UPDATE TEST
SET t_status = REPLACE (first_name, 'T', 'X')
WHERE t_status = 'T' AND t_moddate <= now()- interval(45 minutes);

How to update mysql data with event and remove the event after

I have a mysql table that looks like this
| begintime | endtime | begindate | enddate | state |
+------------+----------+------------+----------+-------+
| TIME | TIME | DATE | DATE | string|
+------------+----------+------------+----------+-------+
I have this code
CREATE EVENT Update
ON SCHEDULE
EVERY 1 SECOND
DO
UPDATE tablename SET tablename.state = CASE
WHEN (SELECT CURRENT_TIME() FROM DUAL)>=tablename.begintime AND (SELECT CURDATE()>= tablename.begindate) THEN "Available"
WHEN (SELECT CURRENT_TIME() FROM DUAL)>tablename.endtime AND (SELECT CURDATE()= tablename.enddate) THEN "Finished"
ELSE "Not Available"
END
I want the server to be always checking if any of those statements is true, and I dont know how to remove the event when:
WHEN (SELECT CURRENT_TIME() FROM DUAL)>tablename.endtime AND (SELECT CURDATE()= tablename.enddate) THEN "Finished
Thanks for your help.
please try this one.
SET GLOBAL event_scheduler = ON;
DROP EVENT IF EXISTS Update1;
CREATE EVENT Update1
ON SCHEDULE
EVERY 1 SECOND
DO
UPDATE tablename SET tablename.state =
CASE
WHEN NOW() BETWEEN CONCAT(tablename.begindate,' ',tablename.begintime) AND CONCAT(tablename.enddate,' ',tablename.endtime) THEN "Available"
WHEN NOW() > CONCAT(tablename.enddate,' ',tablename.endtime) THEN "Finished"
ELSE "Not Available"
END;
To drop the event after setting to "Finished" try using something like this
SET GLOBAL event_scheduler = ON;
DROP EVENT IF EXISTS Update1;
DELIMITER //
CREATE EVENT Update1
ON SCHEDULE
EVERY 1 SECOND
DO BEGIN
SELECT #begindate := begindate,
#begintime:= begintime,
#enddate := enddate,
#endtime := endtime FROM tablename;
IF (NOW() BETWEEN CONCAT(#begindate,' ',#begintime) AND CONCAT(#enddate,' ',#endtime)) THEN
UPDATE tablename SET state = 'Available';
ELSEIF (NOW() < CONCAT(#begindate,' ',#begintime)) THEN
UPDATE tablename SET state = 'Not Available';
ELSEIF (NOW() > CONCAT(#enddate,' ',#endtime)) THEN
UPDATE tablename SET state = 'Finished';
DROP EVENT IF EXISTS Update1;
END IF;
END//
DELIMITER ;

what's wrong with this if/then stored proc?

I'm fuzzy on when I need you use # to reference vars in mySQL. I'm coming from MS SQL where you always use it, but apparently that's not correct in mySQL.
So the below stored procedure is always executing the first IF block, even if the session value is expired - in that it's always executing the update statement. Apparently the only debug tool I could find for mySQL stored procs runs on Windows and Linux. I'm on a Mac. Wamp wamp wamp.
So yeah. Can anyone see what's wrong here? Thanks!
DELIMITER $$
CREATE DEFINER=`xxx`#`localhost` PROCEDURE `validate_session`(uid INT, token VARCHAR(256))
BEGIN
DECLARE sessId INT DEFAULT NULL;
SELECT sessId = id FROM UserSessions
WHERE userId = uid
AND sessionToken = token
AND expires > INTERVAL 2 MINUTE + NOW() ORDER BY expires DESC LIMIT 1;
IF sessId IS NOT NULL THEN
UPDATE UserSessions
SET expires = INTERVAL 2 HOUR + NOW()
WHERE id = sessId;
ELSE
DELETE FROM UserSessions
WHERE userId = uid
AND sessionToken = token;
SET #sessId = 0;
END IF;
SELECT sessId;
END
For the record what it's supposed to do in pseudo code:
if we have a session for this user, with a matching token which has not expired {
update the expiration time to 2 hours from now
return the session id;
}
else {
delete the (now stale) session
return 0;
}
Thanks in advance.
You're not setting the value of sessId... you're making a comparisson in your query.
I think what you need is something like this:
CREATE DEFINER=`xxx`#`localhost` PROCEDURE `validate_session`(uid INT, token VARCHAR(256))
BEGIN
DECLARE sessId INT DEFAULT NULL;
SELECT id
INTO sessId -- Here is the assignment
FROM UserSessions
WHERE userId = uid
AND sessionToken = token
AND expires > INTERVAL 2 MINUTE + NOW()
ORDER BY expires DESC
LIMIT 1;
IF sessId IS NOT NULL THEN
UPDATE UserSessions
SET expires = INTERVAL 2 HOUR + NOW()
WHERE id = sessId;
ELSE
DELETE FROM UserSessions
WHERE userId = uid
AND sessionToken = token;
SET sessId = 0;
END IF;
SELECT sessId;
END
Reference:
MySQL Reference: SELECT ... INTO syntax
MySQL Reference: Local variable scope and resolution

MySQL - Duplicate PK when trigger is fired, but not when record is directly inserted

I have the following MySQL trigger. It is fired for an update on tbl_users. It will either update tbl_user_stats with some information if there already exists a record for that day, or it will insert a new record in tbl_user_stats if there is not a record for that day. action_date is the PK of tbl_user_stats and it holds the date.
drop trigger if exists trigger_update_user_stats_upgrades_and_downgrades$$
CREATE TRIGGER trigger_update_user_stats_upgrades_and_downgrades AFTER UPDATE ON tbl_users
FOR EACH ROW BEGIN
DECLARE date_now int;
IF NEW.premium <> OLD.premium THEN
SET date_now = (SELECT count(*) from tbl_user_stats WHERE DATE(action_date) = CURDATE());
IF date_now > 0 THEN
IF NEW.premium = 0 THEN
UPDATE tbl_user_stats SET downgrades = downgrades + 1 WHERE DATE(action_date) = CURDATE();
ELSE
UPDATE tbl_user_stats SET upgrades = upgrades + 1 WHERE DATE(action_date) = CURDATE();
END IF;
ELSE
IF NEW.premium = 0 THEN
INSERT INTO tbl_user_stats (action_date, downgrades) values (CURDATE() + INTERVAL 1 DAY, 1);
ELSE
INSERT INTO tbl_user_stats (action_date, upgrades) values (CURDATE() + INTERVAL 1 DAY, 1);
END IF;
END IF;
END IF;
END$$
Towards the bottom, I am inserting CURDATE() + INTERVAL 1 DAY for testing purposes. I am trying to simulate an update on tbl_users being performed on the next day. So if today is 11/22/13 I want to pretend that a record in tbl_users is being updated on 11/23/13. If the trigger works correctly, tbl_user_stats should have a new record inserted with the action_date of 11/23/13.
The problem is that when I try to update tbl_users, I get an error that says "Duplicate primary key 11/23/13". However, there is no primary key in tbl_user_stats set to 11/23/13. When I manually insert a new record into tbl_user_stats using 11/23/13 as the PK, there is no problem. The problem only arises when I try to update tbl_users. Why am I getting the Duplicate primary key error?
I have reproduced this error.
This occurs because you're checking condition of "date_now" is checking for CURDATE()
when you're inserting with CURDATE() + INTERVAL 1 DAY
To simulate the next day, you should change all your date comparisons to CURDATE() + INTERVAL 1 DAY
sqlFiddle code with all CURDATE() changed to CURDATE + INTERVAL 1 DAY gets rid of the error.
To reproduce error, just change
SET date_now = (SELECT count(*) from t2 WHERE DATE(start_date) = CURDATE()+ INTERVAL 1 DAY);
to
SET date_now = (SELECT count(*) from t2 WHERE DATE(start_date) = CURDATE());`