Compare date and string in PDO - php

I've got the following PDO statement:
$myquery = SELECT * FROM DATABASE WHERE TABLE(Date) > 2014-04-07
$stmt = $this->pdo->prepare($myquery);
$stmt->execute();
I get the following error:
Operand type clash: date is incompatible with int
How is it possible to compare a Date in PDO?

Surround the date in single quotes when comparing:
$myquery = "SELECT * FROM DATABASE WHERE TABLE(Date) > '2014-04-07'";

I would try it like:
$myquery = SELECT * FROM table WHERE Date > ?
$stmt = $this->pdo->prepare($myquery,array('2014-04-07'));
$stmt->execute();
even better would be a non string for the date i.e. a datetime-object

Related

php MS Access SQL Query with multiple string parameters

I am trying to construct an SQL statement with two string parameters. Essentially I am querying a MS Access table with php.
Is my syntax correct below?
$parm1 = "TPMS";
$parm2 = "Clamp In";
$sql = "SELECT * FROM archive where productfamily like ".$parm1 ."and where productderivative like". $parm2;
Now I have tried a one parameter string called $parm1, The syntax of the string is as below. Please note this is a MS Access table I am querying with php.
$parm1 = "'TPMS'";
Now the corresponding MS Access SQL statement is as follows which works:
$sql = "SELECT * FROM archive where productfamily like $parm1 order by fullname asc"
Now the corresponding MS Access SQL statement with two parameters which does not work. Can somebody tell me why the second parameter does not work in the SQL statement? Is it perhaps my syntax?
$sql = "SELECT * FROM archive where productfamily like $parm1 and "
$sql .= "where productderivative like $parm2 order by fullname asc";
Firstly, you need to enclose your string literals with single quotes: '
$parm1 = "'TPMS'";
$parm2 = "'Clamp In'";
$sql = "SELECT * FROM archive where productfamily like ".$parm1 ."and where productderivative like". $parm2;
Secondly, a LIKE statement is useful with a wildcard character
% The percent sign represents zero, one, or multiple characters
? The question mark(for Access) represents a single character
So that if you are looking for occurences that may include TPMS anywhere after the , you would have
For example:
$parm1 = "'TPMS%'";
$parm1 = "'%TPMS'";
$parm1 = "'%TPMS%'";
$parm1 = "'?T%'";
$parm1 = "'T?%?%'";
$parm1 = "'T%o'";
Which evaluate to the following SQL:
WHERE productfamily LIKE 'TPMS%' --Finds any values that starts with "TPMS"
WHERE productfamily LIKE '%TPMS' --Finds any values that ends with "TPMS"
WHERE productfamily LIKE '%TPMS%' --Finds any values that have "TPMS" in any position
WHERE productfamily LIKE '?T%' --Finds any values that have "T" in the second position
WHERE productfamily LIKE 'T?%?%' --Finds any values that starts with "T" and are at least 3 characters in length
WHERE productfamily LIKE 'T%o' --Finds any values that starts with "T" and ends with "o"
I'll adapt the code from the documentation here https://www.sitepoint.com/using-an-access-database-with-php/ to your situation.
$dbName = $_SERVER["DOCUMENT_ROOT"] . "yourpathhere\archive.mdb";
if (!file_exists($dbName)) {
die("Could not find database file.");
}
$pdo = new PDO("odbc:DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=$dbName; Uid=; Pwd=;");
$parm1 = 'TPMS';
$parm2 = 'Clamp In';
$sql = 'SELECT * FROM archive where productfamily like :family and where productderivative like :derivative';
$pdo->prepare($sql)
$pdo->bindParam(':family', $parm1, PDO::PARAM_STR);
$pdo->bindParam(':derivative', $parm2, PDO::PARAM_STR);
$pdo->execute();
That should get you there. This is untested. If anything fails, let me know and I'll create some tables and run it.

SQL Variable Inserting INSIDE mysql_query

I am trying to make a price slider with PHP and SQL , but i have a problem when i have some problem in this code
$query = mysql_query("SELECT * FROM price WHERE phone_price BETWEEN" .$from. "AND" .$to. );
while($row = mysql_fetch_array($query)){
print $row['phone_name'];
print $row['phone_price'];
print '';
}
I want to run the SQL query like SELECT * FROM price WHERE phone_price BETWEEN 300 AND 500
I am making a beta version therefore i am accepting the $from and $to values from <input> , i think i am making the error in inserting the variable in mysql_query .
THE ERROR -Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in C:\xampp\htdocs\login\slide\slide.php on line 28
You have a mistake in your query. Spaces needed after BETWEEN and AND. Otherwise php reads your query like ...BETWEEN123AND1234.... And you should better use quotes to place vars:
$query = mysql_query("SELECT * FROM `price` WHERE `phone_price` BETWEEN '".$from."' AND '".$to."'");
Use PDO build-In object. mysql_ functions were deprecated.
Initialize connection.
$dsn = "mysql:host=localhost;dbname=my_database";
$pdo = new PDO($dsn, $login, $password);
Use prepare statement.
$sh = $pdo->prepare("SELECT * FROM price WHERE phone_price BETWEEN :from AND :to");
Bind values and value types.
$sh->bindParam(':from',$from,PDO::PARAM_INT);
$sh->bindParam(':to',$to,PDO::PARAM_INT);
Fetch results into assoc array.
$res = $sh->fetch_all(PDO::FETCH_ASSOC);
Good Luck

PHP Oracle SQL Select date to_char

I am getting; "Warning: oci_execute(): ORA-00904: "JAN": invalid identifier", when I try to execute these commands:
function stime($conn3, $time){
$result = oci_parse($conn3, "SELECT TO_CHAR($time, 'mm/dd/yyyy') FROM MON_EVENTS")or die(oci_error());
oci_execute($result);
}
STIME is also a date field in the database.
I am passing the STIME field to $time as stime($row_oci['STIME']).
You were bitten by PHP string interpolation:
$result = oci_parse($conn3, "SELECT TO_CHAR($time, 'mm/dd/yyyy') FROM MON_EVENTS")or die(oci_error());
// ^^^^^
$time is replaced by its content converted to a string -- and that before passing the value to the oci_parse function. As the string representation of a date might contain spaces, letters, /, ... it will confuse the Oracle SQL parser that report ORA-00904: Invalid identifier.
As of myself I would suggest to use bind parameter instead. This is much less error-prone -- and much more safe:
$result = oci_parse($conn3, "SELECT TO_CHAR(:time, 'mm/dd/yyyy') FROM MON_EVENTS");
oci_bind_by_name($result, ':time', $time);
$id = $row_oci['ID'];
$result = oci_parse($conn2, "SELECT TO_CHAR(STIME,'MON/DD/YY hh24:mm:ss') FROM MON_EVENTS WHERE ID = $id");
oci_execute($result);
while($row_result = oci_fetch_array($result)){
echo "". $row_result['0'] ."";}

PHP PDO statement to filter records

I am using PHP PDO to retrieve objects to an iOS app via JSON.
There is a database table with event objects. It has three fields to store day, month and year. The owner of the database doesn't want to store dates in a date field, that means that I have to deal with it.
The app sends a URL with params,like this:
http://..hidden domain./myfile.php?dia_inicio=16&dia_final=15&mes_inicio=11&mes_final=12&ano_inicio=2014&ano_final=2015
That means that I am looking for events from 16Nov2014 to 15Dec2015.
This is my PHP code:
$sql = 'SELECT * FROM tbagenda WHERE (dia_evento => :di AND mes_evento = :mi AND ano_evento = :ai) OR (dia_evento <= :df AND mes_evento = :mf AND ano_evento = :af) ';
// use prepared statements, even if not strictly required is good practice
$stmt = $dbh->prepare( $sql );
$stmt->bindParam(':di', $dia_inicio, PDO::PARAM_INT);
$stmt->bindParam(':df', $dia_final, PDO::PARAM_INT);
$stmt->bindParam(':mi', $mes_inicio, PDO::PARAM_INT);
$stmt->bindParam(':mf', $mes_final, PDO::PARAM_INT);
$stmt->bindParam(':ai', $ano_inicio, PDO::PARAM_INT);
$stmt->bindParam(':af', $ano_final, PDO::PARAM_INT);
// execute the query
$stmt->execute();
// fetch the results into an array
$result = $stmt->fetchAll( PDO::FETCH_ASSOC );
// convert to json
$json = json_encode( $result );
// echo the json string
echo $json
How should I change my statement to make it work with dates like: 16Nov2014 to 28Nov2014 (same month), 16Nov2014 to 5Dec2014 (different month, same year) and 16Nov2014 to 02May2015(different year)?
ADDED LATER:
iOS log to show the URL send to the PHP file:
recuperar_eventos_dia.php?dia_inicio=11&dia_final=26&mes_inicio=11&mes_final=11&ano_inicio=2014&ano_final=2014
PHP part:
$start = "$ano_inicio-$mes_inicio-$dia_inicio";
$end = "$ano_final-$mes_final-$dia_final";
// In the SQL, concatenate the columns to make a YYYY-MM-DD date string
// and cast it to a MySQL DATE type.
// That makes it possible to use BETWEEN
$sql = 'SELECT
*
FROM tbagenda
WHERE STR_TO_DATE(CONCAT_WS('-', ano_evento, mes_evento, dia_evento), "%Y-%m-%d")
BETWEEN :start AND :end';
// Bind and execute the statement with 2 parameters:
$stmt = $dbh->prepare( $sql );
$stmt->bindParam(':start', $start, PDO::PARAM_STR);
$stmt->bindParam(':end', $end, PDO::PARAM_STR);
$stmt->execute();
// fetch, etc...
$result = $stmt->fetchAll( PDO::FETCH_ASSOC );
// convert to json
$json = json_encode( $result );
// echo the json string
echo $json;
And now a screenshot from the table tbagenda:
I'm sorry that you're stuck with this unfortunate table structure.
I would suggest concatenating the table's columns to form usable date strings, and cast them to a date value via MySQL's built in function STR_TO_DATE(). Do the same with your query string input values to make proper date comparisons with a BETWEEN operator.
// Begin by concatenating the input values into single date strings YYYY-MM-DD
$start = "$ano_inicio-$mes_inicio-$dia_inicio";
$end = "$ano_final-$mes_final-$dia_final";
// In the SQL, concatenate the columns to make a YYYY-MM-DD date string
// and cast it to a MySQL DATE type.
// That makes it possible to use BETWEEN
$sql = "SELECT *
FROM tbagenda
WHERE STR_TO_DATE(CONCAT_WS('-', ano_evento, mes_evento, dia_evento), '%Y-%m-%d')
BETWEEN :start AND :end";
// Bind and execute the statement with 2 parameters:
$stmt = $dbh->prepare( $sql );
$stmt->bindParam(':start', $start, PDO::PARAM_STR);
$stmt->bindParam(':end', $end, PDO::PARAM_STR);
$stmt->execute();
// fetch, etc...
$result = $stmt->fetchAll( PDO::FETCH_ASSOC );
The string operations will affect performance of this query. It would be better, as you know, if the dates were stored as a proper DATE so MySQL would not need to cast them for comparisons. They could also then be indexed.
Note also that I did not include validation of the date strings. You might consider checking them to be sure they make valid dates before executing the query.
// strtotime() would return false for invalid date strings...
if (strtotime($start) && strtotime($end)) {
// The dates are valid, and so you can proceed with the query
$sql = 'SELECT.....';
}

Prepare seems to be stripping quotes from string so that it is not accepted by the mysql datetime field

I would like to update a DATETIME mysql field using a php STRING in a prepared statement
$stmt = $mysqli->prepare("UPDATE TABLE1 SET DATETIME1 = ? where ID = ?");
$stmt->bind_param('si',$date,$id);
$date = "2013-12-04 00:00:00"; /*string '2013-12-04 00:00:00' (length=19)*/
$id = 4;
$stmt->execute();
I had expect that mysql should treat the statement as
UPDATE TABLE1 SET DATETIME1 = '2013-12-04 00:00:00' where ID = ?;
/*which works when directly entered*/
However I assume it is treating like
UPDATE TABLE1 SET DATETIME1 = 2013-12-04 00:00:00 where ID = ?;
/*giving the result of null*/
I have tried adding using the STR_TO_DATE mysql function to force it to treat the $date as a string and then convert it to DATETIME. ie
$stmt = $mysqli->prepare("UPDATE TABLE1 SET DATETIME1 = STR_TO_DATE(?,'%Y-%m-%d %T') where ID = ?");
/*again the result is null*/
Do I need to bind a quoted string? what am I missing?
It makes no much sense to prepare it, bind it and then execute it in such an obscure way. Besides the problems outlined on the comments, consider changing it to:
$date = "2013-12-04 00:00:00"; /*string '2013-12-04 00:00:00' (length=19)*/
$id = 4;
$stmt = $mysqli->prepare("UPDATE TABLE1 SET DATETIME1 = ? where ID = ?");
$stmt->execute(array($date, $id));
Besides, you were binding them wrong. You were using the prepare statement but then binding three values (or two values and a wrongly set parameter). Please refer to the documentation for more info about binding parameters.
Note that with PHP >= 5.4 you can simply do:
$date = "2013-12-04 00:00:00"; /*string '2013-12-04 00:00:00' (length=19)*/
$id = 4;
$stmt = $mysqli->prepare("UPDATE TABLE1 SET DATETIME1 = ? where ID = ?");
$stmt->execute([$date, $id]);

Categories