CakePHP: Search BETWEEN datetimes and validate form - mysql

I'm stuck with this. My own skills aren't enough to solve this myself.
I have a form with these fields:
PLACE_ID
START_DATE (DATETIME)
END_DATE (DATETIME)
What I try to achieve:
If there are already bookings in database in the same time range,
in the same place, the submit will fail.
So, the query would look something like this:
SELECT *
FROM bookings
WHERE place_id=".$_POST['placeId']."
AND('".$_POST['startDate']."'
BETWEEN start_date
AND end_date
OR '".$_POST['endDate']."'
BETWEEN start_date
AND end_date)"
If this returns NULL, the submit will success. How to get this working with CakePHP? Please, help...

From a separation of logic perspective, I think this should be handled in your controller. Building from Ollie Jones advice, upon post-back from the user's browser, you should do something like the following:
$this->Booking->find('all', array('conditions' => array('Booking.start_date BETWEEN' => array($new_start_date, $new_end_date), 'Booking.end_date BETWEEN' => array($new_start_date, $new_end_date))
$new_start_date should be set to $this->data['Booking']['start_date'] and the same goes for $new_end_date. The answer just starts to look messy otherwise!
If the query returns nothing then you can go ahead and save your new booking. If there are bookings, you should advise your user accordingly.

The comments warning you about SQL injection are correct.
Using BETWEEN for DATETIME data type search is problematical. I'm not sure this is your problem, but it might be.
Consider a DATETIME value of, say, '2013-04-13 11:00:00' You'd think this would be BETWEEN '2013-04-13' AND '2013-04-13', but it isn't, because it's after '2013-04-13 00:00:00'.
One of the unpleasant problems with this use of BETWEEN is that single day ranges don't work.
What you need for a date range match is
date_to_test >= start_date
AND date_to_test < end_date + INTERVAL 1 DAY

Related

How to calculate the difference between days in a table field

Ok this should be a relatively easy thing to do, yet I'm at the head desk stage trying to figure out the insanity here.
I have a table called tblPersonnel. I'm tracking two document expiration dates in date/time fields called CED and PPED. When I run a query against tblPersonnel I need it to look at PPED, determine if that document is expired and if so use CED instead. I have a few fields in the query that need to use this concept to determine what the output value is, but I am hitting a wall here trying to get the query to spit out the correct value. Here's what I'm using for one of the fields - Document Expiration Date: IIf([PPED]-Now()<0,[CED],[PPED]). What's happening is that the expression is constantly popping as false, so PPED is getting used regardless if it's an expired date or not. Does anyone have any ideas as to what I'm doing wrong here?
I've also tried to set this up as its own field in tblPersonnel, but that's even more aggravating. If I try to set the field to just a text field - IIf([PPED]-Now()<0,"Yes","No"), the formula will accept the use of Now(), but it doesn't like the reference to the other fields in the table. If I set it as a calcuated column, I can reference the other fields but it doesn't like Now(). I'm at a loss here.
If PPED is less than Date(), it is expired. Don't need to subtract. Assuming CED and PPED are just date parts, no time, consider:
IIf([PPED] < Date(), [CED], [PPED])
If PPED could be null:
IIf(Nz([PPED],0) < Date(), [CED], [PPED])
Ok finally fixed it here. I had another issue in that I wasn't accounting for how Access would handle a Null or blank value in PPED. The functioning formula is Document Expiration Date: IIf(Len([PPED])>0,IIf([PPED]<Date(),[CED],[PPED]),[CED]) Thanks to June7 for helping me simplify the expression, as I was using DateDiff('d',[PPED],Date())<0 but their answer is just so much cleaner and quicker to type.

Specifying date range in a request in MySQL

I have a table with some info about trade goods, kinda logistics. It has a column called 'arriving_date', which contains the arrival dates in a format like this "30.06.2019".
Now I need to enter a request which displays only the goods which have not arrived yet, in other words which arrival date is > 30.06.2019. So I'm entering my request
SELECT *
FROM traffic
WHERE arriving_date > '30.06.2019'
But this request shows me just blank field. And I think I've already guessed why. Apparently it can't compare numbers in a format like that. But I'm not sure how should I make it compare dates then. Help is appreciated.
Assuming that arriving_date is just a string (and not an actual date)
SELECT *
FROM traffic
WHERE str_to_date(arriving_date, '%d.%m.%Y') > now()
OR arriving_date is null;
This will convert the arriving_date string into a date and compare it to the current date and time.
I also added a check for arriving_date being null (ie not set) in case it's set upon arrival.
Note that using a function on the value from a column makes all queries run full table scan. There is no way around that since your date format is as it is.
Thanks everyone for help!
I manage to solve my problem this way:
1. I changed arriving_date data type to 'date' (it was integer)
2. I rewrote dates from format 'dd.mm.yyyy' to 'yyyy-mm-dd', not sure if it matters.
3. final request looks like this:
SELECT *
FROM traffic
WHERE arriving_date > NOW()
It works perfectly now.
assuming that the arriving_date column is a porper date data type try convert the date string in a proper date
SELECT *
FROM traffic
WHERE arriving_date > str_to_date('30.06.2019', '%d.%m.%Y')
or if both date

Searching Between dates where STOP date is null

I need your help.
The following is my database table.
http://i42.tinypic.com/10xh4j7.png
A small request to please have a look at the image.
My problem is, when I want to retrieve the rate from date_from and date_to.
For Eg: Lets say retrieving_date = 2013-11-14.
rs = stat.executeQuery("select rate from rate_chart where '"+retrieving_date+"' BETWEEN date_from AND date_to");
This query gives me my required result, for the 11th month.
I get 10.40 as my required rate with the above query.
Lets say, rate has never been changed since 2013-11-26, and now my retrieving_date is 2013-12-20. And now, when I try to execute the above query, it doesn't work. No errors but doesn't give me the last rate. In my case, is 10.80 as mentioned in the above image.
I actually want to search between dates even if the stop date or (date_to) is null.
No, idea how to go forth with this. Stuck for a while now.
Any help would be greatly appreciated.
if the stop date (or date_to) is null, set it to the current date.

MySQL date function (Say May-10 to be saved as 2010-05-01)

T've the date column with value like 'May-10' (Say %b-%y format).While loading data to mysql, i use like
SET Period = STR_TO_DATE(#var1,'%b-%y')
Then the values are stored as '2013-05-00'. But i want to save those values in any date number
(say '2013-05-01').
I tried like doing this for May-10
DATE_ADD(DATE_SUB(DATE_FORMAT(LAST_DAY(STR_TO_DATE('May-10','%b-%y')),'%Y-%m-%d' ),INTERVAL 1 MONTH),INTERVAL 1 DAY)
I know that this is a complex way of doing things.
Anyone please suggest me simple solutions ?
Try this
SET Period = STR_TO_DATE(CONCAT('01-', #var1),'%d-%b-%y')

Last Active List - VB.NET

I've got a client application that's going to update a database every five minutes with the current time, and then I want to output this time as a last active table in a seperate VB application.
I know about mysql time, but I don't quite understand how I can use it to display when a client was last active.
I've looked around and found some stuff about mysql times but I don't fully understand it.
Any help would be great, I'm going to place the results in a ListView with 'Client Name' and 'Last Active' if this helps, and I already know how to connect to my database and retrieve information.
Thank you.
I'd recommend using a DATETIME for storage. The TIME data type is limited to a single "time of day" or a timespan. True, you're looking for the time of day, but to calculate the "Last Active" time you need the date attached. Consider these "Last Active" values (using a 24-hour clock):
3/26/2013 at 17:00:00 <-- this has the maximum time (5PM), but...
3/27/2013 at 08:15:00 <-- ...this is the most recent time because it happens the following day
In other words, you need the date so you can sort the time.
The MySQL DATETIME data type should be supported by VB.NET, but I've never used the two together so I can't guarantee it. To query and report just the time component of the date you have a ton of options. Here are two:
Query the entire date/time from MySQL and return it as a System.DateTime value to VB.NET. In VB.NET you can format it using DateTime.ToString to show only the time components. The MySQL query would go something like this:
SELECT ClientName, MAX(LastActive) AS LastActiveDateTime
FROM your_table
GROUP BY ClientName
Format the time in MySQL and return it as a String to VB.NET. In VB.NET you'll just need to display the string as is. The MySQL query would go something like this:
SELECT ClientName, DATE_FORMAT(MAX(LastActive), '%r') AS LastActiveTime
FROM your_table
GROUP BY ClientName
The format code %r in the above query will return the time in a 12-hour format with AM/PM, for example 07:55:29 PM. To return a 24-hour format (19:55:29), use %T instead.