I would like to create an event in MySQL in order to change a value in a table. The event checks whether a date (particularly, the TIME() part of a TIMESTAMP field) is more than the current date. Obviously, I have a time_stamp and an active column in a table named 'active'. This is what I have
CREATE EVENT update_status
ON SCHEDULE EVERY 2 SECOND
DO
SELECT #time:= time_stamp FROM active WHERE user_id = 1;
SELECT #time2:= TIMESTAMP(#time);
SELECT #active:=TIMEDIFF(#time2,DATE_ADD(NOW(),INTERVAL -15 SECOND));
UPDATE active SET active=if(TIME_TO_SEC(TIME(#active))>=0,1,0) WHERE user_id=1;
As far as I have seen, the SELECT part with the variables works fine, that is, TIME_TO_SEC(TIME(#active)) looks like a regressive count starting with 15 (provided I updated the 'time_stamp' field properly).
The intended behavior is that when TIME_TO_SEC(TIME(#active)) reach 0, the UPDATE query would change the value of the 'active' field from 1 to 0 (the default value is 1). However, it doesn't do anything.
UPDATE: To be precise, sometimes it changes the value to 0 but when TIME_TO_SEC(TIME(#active)) is still positive.
SECOND UPDATE: I recently tried this one:
CREATE EVENT update_status
ON SCHEDULE EVERY 2 SECOND
DO
SELECT #time:= time_stamp FROM active WHERE user_id = 1;
SELECT #time2:= TIMESTAMP(#time);
SELECT #active:=TIMEDIFF(#time2,DATE_ADD(NOW(),INTERVAL -15 SECOND));
UPDATE active SET active=0 WHERE user_id=1 AND TIME_TO_SEC(TIME(#active))>=0;
which didn't work either.
THIRD UPDATE: I used the suggestion by Adam and I even if it doesn't work as expected, it certainly changes the value 'active' to 0, immediately after I start the event. Ideas?
SOLUTION: Thanks to Adam, I used his code with an IF statement:
CREATE EVENT update_status
ON SCHEDULE EVERY 2 SECOND
Do
UPDATE active AS t
SET t.active=IF(TIME_TO_SEC(TIMEDIFF(
t.time_stamp, DATE_ADD(NOW(),
INTERVAL -15 SECOND)))>=0,1,0)
WHERE user_id=1
which it works as intended. I don't why his suggestion didn't work, though.
Where did I make a mistake?
Of course, another approach to get this functionality would be greatly appreciated.
Thanks in advance.
What is the value in active.time_stamp where active.user_id = 1?
Also, I think that your statement might be written more simply.
If time_stamp in fact contains timestamps then you don't need the call to TIMESTAMP().
Remove TIME() function from UPDATE query because TIMEDIFF(expr1,expr2) returns expr1 – expr2 expressed as a time value.
So this is how I wrote your statement:
CREATE EVENT update_status
ON SCHEDULE EVERY 2 SECOND
DO
UPDATE active t
SET t.active = 0
WHERE t.user_id = 1
AND TIME_TO_SEC(
TIMEDIFF(
t.time_stamp, DATE_ADD(NOW(),INTERVAL -15 SECOND)
)
)>=0;
I've tested that when the value in active.time_stamp is greater than now, this event sets the value in active.active to 0.
If that still isn't working you might also try something very basic like:
CREATE EVENT update_status_test
ON SCHEDULE EVERY 1 SECOND
DO
UPDATE active t
SET t.active = 0
WHERE t.user_id = 1;
And if that still isn't working then make sure the event scheduler is actually running. There are several ways to start it, this is one: SET GLOBAL event_scheduler = 1
Other notes:
This may not matter now, but as time goes on you will eventually run into the upper-limit of the TIME type in MySQL.
Related
I have a table in my MYSQL database called sale as shown below:
I want to auto delete the sales that are 3 days old and not validated,
I create event but unfortunately it doesn't work here's my code :
CREATE EVENT `delete_sale` ON SCHEDULE EVERY 1 HOUR DO DELETE FROM sale WHERE sale.is_validated = 0 and sale.date < DATE_SUB(NOW(), INTERVAL 3 DAY)
My best guess is that your event is working, but it's only firing once then deactivating. To fix that, you should add the "ON XOMPLETION PRESERVE" line. Another possibility is that it's not loading properly because it can't quite parse your event code. To really hold MySQL's hand with this, try treating it like a multi statement event, changing the delimiter and adding BEGIN and END. Something like this:
DELIMITER &&
CREATE EVENT `delete_sale`
ON SCHEDULE EVERY 1 HOUR
ON COMPLETION PRESERVE
DO
BEGIN
DELETE FROM sale WHERE sale.is_validated = 0 and sale.date < DATE_SUB(NOW(), INTERVAL 3 DAY);
END &&
DELIMITER ;
the problem resolved by enabling event_scheduler with the following query SET GLOBAL event_scheduler = ON;
Lets say I have a Table tbl_Room with a column taken (boolean) and a Customer wants to rent this room for a short period.
Now, can I tell mysql to change the value of taken automatically depending on the timestamp, e. g. if the rent time/period is over, the value of taken should set automatically to false.
Or do I need to update my database with CRON or some other script that runs on the server periodically?
Please use mysql event to manage it.
CREATE EVENT [IF NOT EXIST] event_name
ON SCHEDULE schedule
DO
event_body
Reference
Under event_body you can write select statement to check period and then update table if period is over.
The best way to handle this sort of time-based request is counterintuitive.
Don't try to update the table at a specific time. Instead, include a timestamp column called something like lease_expires_at.
When you rent a room, update the row to set the value of lease_expires_at to the time at which the rental period expires. For example, if you rent a room for 30 minutes, starting now, do this.
UPDATE room
SET lease_expires_at = NOW() + INTERVAL 30 MINUTE
WHERE room_number = whatever
If you want to know whether a room is presently (NOW()) taken, do this:
SELECT room_number,
CASE WHEN lease_expires_at IS NULL THEN 0
WHEN lease_expires_at <= NOW() THEN 0
ELSE 1 END taken
FROM room
WHERE room = whatever
If you want to know whether a room will be available one hour from now (NOW() + INTERVAL 60 MINUTE), do this:
SELECT room_number,
CASE WHEN lease_expires_at IS NULL THEN 0
WHEN lease_expires_at <= NOW() + INTERVAL 60 MINUTE THEN 0
ELSE 1 END taken
FROM room
WHERE room = whatever
Then, once in a while, but not in any time-critical way, you can clean things up using a query like this
UPDATE room SET lease_expires = NULL WHERE lease_expires <= NOW()
You can use an event, or an overnight cronjob, or whatever you wish, to do this cleanup. The integrity of your application doesn't depend on exactly when this job runs.
The advantage of this should be clear: If you rely on some regularly running process to set an taken column value, and that process doesn't run or runs late, you get bad results. When you rely on the time, you get accurate results.
There's a small boundary-condition detail in this design. By using <= in my queries, I'm choosing to have the lease_expires_at timestamp represent the very first moment at which the room is available for another lease, not the last moment of the present lease. That's a handy choice, because if you put something like 2017-11-2017 11:00:00 into lease_expires_at, and somebody says "is the room available at 11:00?" you want to be able easily to say "yes." The guy who rented it at 10:30 gets it until the moment before 11:00.
you can use jquery time picker....after u can create a if loop in which JavaScript time function will check current time...to its original time...if condition is satisfied...we can change the mysql taken function
I am writing a MySQL Database and I wish to do the title within the MySQL database itself via Events if possible. I am updating the database via a Windows Service written in VB.net and have no desire to do the below via a separate 'server control' type program.
Basically, I have written the below in to the Database, but it doesn't quite do what I want:
Create Event MachineOffline
On
SCHEDULE Every 2 Minute
Do
UPDATE maindb.monitortable SET Online='1';
I would like it to say something like the below:
Create Event MachineOffline
On
SCHEDULE Every 2 Minute
Do
IF **RowX updated < 2 minutes ago** then
UPDATE Database.Table SET Online='0' where RowX(ID);
I have no idea how to achieve this hence my question to everyone. I have no desire to create
If you give your Database.Table an extra column, lets say, last_updated timestamp, you can then update it like so:
update Database.Table
set online=0, last_updated = now()
where last_updated <= now() - interval 2 minute
and online=1
I have been developing ban system with temporary banning system and I'm looking if there's anyway to update a row to specific value using a timer within MySQL. For instance,
I need my field banned to be set to 0 where the rowid is X.
UPDATE mytable SET banned=0 WHERE rowid=X
- But this query has to be done within X minutes or seconds specified, like if we could delay it.
Banning a user temporarily for 60 seconds, query sent at that time:
"UPDATE mytable SET banned=1, unbanon=NOW()+60 WHERE rowid=X".
Could I possibly get MySQL to automatically set banned variable to 0 after 60 seconds has passed?
Thank you.
Set a cron job to run a query every minute that will do something like :
UPDATE mytable SET banned=0 WHERE unbanon <= NOW() AND banned=1
I am trying to do some basic estimating of how long users spend on a site. I have a simple polling script in javascript that hearbeats out to a php script. I'm trying to do the following in one sql statement:
calculate the difference between now and the last updated_on field (which is a datetime field ) and add it to the current active_time field (which is just an integer)
Then update the updated_on to reflect that the record has been updated
This is the sql I'm trying to use;
UPDATE login_log
SET active_time = active_time + ( SELECT TIME_TO_SEC( TIMEDIFF( NOW(), updated_on ) ) ),
updated_on = NOW()
WHERE user_id = ? && session_id = ? AND status = 'active'
Question 1 - I'm assuming I can update updated_on and still use it to calc the difference and not have a race condition, but can someone confirm or tell me that doesn't work?
Question 2 - I must be doing something else wacky because after abit, the active_time is way off as in it thinkgs it's been going for hours when it's only been 20 minutes. Not really scope of this quesiton, but if anyone sees anything quickly that is wrong, I'd appreciate knowing ....
TIA
This seems like the wrong way to go about this. I would simplify it having two fields, created and updated_on, which I would call last_updated. To calculate the current time on the site you would simply subtract the created value from the current time. Presumably, you want some permanent record as well. That comes from the last_updated field, which is updated each time a request from the user is seen (including your heartbeat). You simply update it with the current time. The difference between created and last_updated becomes your permanent record of the time on site.