I have a table called pages in mysql with columns:
ID int NOT NULL PK,
end_time TIMESTAMP,
active BIT
I'm setting the end_time as an expiration timestamp, so when a row is created active is set to 1 and end_time to the expiration date/time.
Is there a way to create a trigger or something similar so that when the end_time is simply reached it sets active to 0?
I don't know if triggers would be the best way to go, or how I should set that up, but it seems within the realm of what I should be doing.
Any help much appreciated.
You could use events as a periodic time based deletion/set active=0.
If the end_time needs to be strict, keep active=0 AND end_time <= NOW() in your queries that retrieve the entries.
Related
I need to make a query that checks if the start and endtime that a user wants to plan something aren't already planned
I currently have this query:
select *
from planned_activities
where
user_id = 161
and
'2022-01-11 17:36:00' between start_time and end_time
or '2022-01-11 18:36:00' between start_time and end_time
or ('2022-01-11 17:36:00' <= start_time and '2022-01-13 18:36:00' >= end_time);
I find it hard to explain but I basicly want to return the data from the other planned activity if the planning isn't possible.
SELECT EXISTS ( SELECT NULL
FROM planned_activities
WHERE #current_user_id = planned_activities.user_id
AND #planned_activity_start < planned_activities.end_time
AND #planned_activity_end > planned_activities.start_time ) row_exists
The query checks does the row for current user which overlaps with entered time range exists. Returns one row with one column row_exists, possible values are 1 (the overlapping is found) or 0 (entered time range is free).
If adjacent time ranges are not allowed too then use weak comparing operators.
I have in my DB (db_test) a table (tb_test) with 3 columns (id, test_field, timestamp_ins, timestamp_mod).
id is the 'primary key' with auto-increment attribute;
test_field is a char(1) that can contains only 2 values ('N' or 'S');
timestamp_ins is a datetime with current timestamp (not updating);
timestamp_mod is a datetime with current timestamp set to ON UPDATE CURRENT_TIMESTAMP().
I would like test_field automatically returns to default value ('N') 30 minutes after last modify of record indicated in timestamp_mod value.
I'm not expert in mysql, so I need help about this.
Is it possible using phpMyAdmin on a XAMPP virtual server?
--UPDATE--
Solved with this syntax:
CREATE EVENT IF NOT EXISTS test_event
ON SCHEDULE EVERY 1 MINUTE
DO
UPDATE ni0y2__test
SET test_field = DEFAULT
WHERE test_field < NOW() - INTERVAL 30 MINUTE
Only one doubt:
can this event make my DB performances worse?
I prefer putting the onus on the reader, not the table:
SELECT IF (timestamp_mod < NOW() - INTERVAL 30 MINUTE,
'N',
test_field) AS funky_field
FROM tb_test;
EVENTs have some overhead. Also, the above method will change at precisely 30 minutes; any attempt at using EVENT will be only approximately 30.
You could "hide" the IF(...) from the users by using a VIEW or Stored Function or a GENERATED column.
I'm wondering if there is any way to schedule an update where I update a tables data on expiration of the old one.
E.g. John Smith has an active service at Company X, but wants to upgrade the service. However, due to restrictions to his current agreement the new service doesn't take effect until X days.
Is there any way to store the new data and update it at the end of a month in MySQL? If yes, would this require me to have another table with the new order data stored?
Often this requirement for changing things at future times is handled by placing start_date and end_date columns in your services table.
Then you can find presently active service rows with
SELECT user_id, whatever, whatelse
FROM services
WHERE (start_date IS NULL OR start_date <= NOW())
AND (end_date IS NULL OR end_date > NOW());
You can, if you wish, create a view called active_services automatically filtering the services table for currently active services.
CREATE VIEW active_services AS
SELECT *
FROM services
WHERE (start_date IS NULL OR start_date <= NOW())
AND (end_date IS NULL OR end_date > NOW());
Note -- in this design end_date contains not the last moment the service is active but the first moment it becomes inactive. If end_date is null the service continues to be active.
To change a service or user_id at the beginning of next month you do these two operations:
UPDATE service
SET end_date = LAST_DAY(NOW()) + INTERVAL 1 DAY
WHERE user_id = <<user id you wish to change >>
INSERT INTO service (start_date, user_id, whatever, whatelse)
VALUES (LAST_DAY(NOW()) + INTERVAL 1 DAY,
<<user id you wish to change >>,
<<whatever>>,
<<whatelse>>;
Then, when next month arrives the active_services view returns the new service. This is much more robust than relying on a precisely timed monthly job. If you do a monthly job, it can run anytime. It simply cleans up expired services.
You can use MySQL events to run particular jobs at appointed times. (But some shared MySQL systems don't let you use events.)
Interestingly mysql has event schedulers have a look at the documentation.
below is an example of a minimal CREATE EVENT statement:
CREATE EVENT myevent
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR
DO
UPDATE myschema.mytable SET mycol = mycol + 1;
The previous statement creates an event named myevent. This event executes once—one hour following its creation—by running an SQL statement that increments the value of the myschema.mytable table's mycol column by 1.
If yes, would this require me to have another table with the new order data stored
I am not sure if you need another table or so...it purely depends on how you want it to be one
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 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.