I am using that code without any problem via non-pdo.
mysql_query("
SELECT * FROM table
WHERE date_start >= '$date_start'
and date_end <= '$date_end'
");
But when I try using with pdo, code didn't work.
$query = $this->db->prepare("
SELECT * FROM table
WHERE date_start >= :date_start
and date_end <= :date_end
");
$query->execute(array(
'date_start'=>'2017-05-01 00:00',
'date_end'=>'2017-05-30 00:00'
));
Can I get help? Where is problem?
MORE INFO : (EDITED)
System : Windows (Appserv)
PHP Version : 5.6.30
I didn't see any error in error.log file.
I guess problem coming from $params array. Because worked like this:
$query = $db->prepare("SELECT * FROM brands WHERE brand_status=:brand_status and date_start >= :date_start and date_end <= :date_end");
$query->execute(array('brand_status'=>$brand_status, 'date_start'=>$date_s, 'date_end'=>$date_e));
But when I used execute(array($params)) not working. Actually if I not use date parameters working, but when I use date parameters not working. My example code below:
$extra = '';
$params = array();
$sql = "SELECT * FROM brands ORDER BY brand_name";
$brand_status = "1";
$brand_name = "";
$date_start = "2017-05-01 00:00:00";
$date_end = "2017-06-30 23:59:59";
if ($brand_status) {
$extra .= "brand_status=:brand_status and ";
$params[] = array("brand_status" => $brand_status);
}
if ($brand_name) {
$extra .= "brand_name LIKE :brand_name and ";
$params[] = array("brand_name" => "%" . $brand_name . "%");
}
if (dbDate($date_start)==1 and dbDate($date_end)==1)
{
$extra .= "date_start >= :date_start and date_end <= :date_end and ";
//problem here:
$params['date_start'] = $date_start;
$params['date_end'] = $date_end;
}
if (count($params) > 0) {
if (strlen($extra) > 0) {
$extra = rtrim($extra, ' and ');
}
$sql = "SELECT * FROM brands WHERE $extra ORDER BY brand_name";
$query = $db->prepare($sql);
$result = $query->execute($params);
} else {
$result = $query = $db->query($sql);
}
if($result)
$num = $query->rowCount();
if($num > 0) {
while($row = $query->fetch()) {
echo $row['brand_name'] . "<br>";
}
}
function dbDate($value)
{
$pattern = "/^1|2[0-9]{3}\-(0[1-9]|1[0-2])\-(0[1-9]|[1-2][0-9]|3[0-1])( [0-9]{2}:[0-9]{2}(:[0-9]{2})?)?$/";
if (preg_match($pattern, $value, $m)) { return 1; } else { return 0; }
}
How can I fix that $params problems for dates? Phil sorry my English is not good. I didn't understand totally your suggestions. I guess you found reason of problem.
execute(['date_start' => $date_start, 'date_end' => $date_end])
Finally I found reason of problem and I fixed my problem. Actually $params haven't any problem in execute array for dates too. Problem coming from $extra=rtrim($extra, ' and '); I changed to $extra=substr($extra, 0, -5); again and problem fixed.
This is correct sql with substr:
date_start >= :date_start and date_end <= :date_end
rtrim didn't give any error for other parameters but when I used rtrim for date_end sql it happened this way:
date_start >= :date_start and date_end <= :date_e
(nd character removed from date_end in sql)
Thanks your answers and your suggestions.
Related
When searching for available cars, I'm trying to SELECT from cars table WHERE the IDs do not include the already booked cars.
For that, I used :
$result = $pdo->prepare("SELECT * FROM cars
WHERE id NOT IN (" . implode(',', $bookedCarIds) . ")
AND (location = '$fromlocation' AND fromdate BETWEEN '$fromdate' AND '$todate')
");
$result->execute();
$availableCars = [];
$availableCars = $result->fetchAll();
Which works perfectly fine.
However, the issue arises when there are no already booked cars in the selected location and dates (where $bookedCarsIds is NULL). To deal with this issue, I used the following code, which throws a syntax error.
$result = $pdo->prepare("SELECT * FROM cars
WHERE id NOT IN (" . implode(',', $bookedCarIds) . ") AND
(location = '$fromlocation' AND fromdate BETWEEN '$fromdate' AND '$todate')
OR WHERE location = '$fromlocation' AND fromdate BETWEEN '$fromdate' AND '$todate'
");
$result->execute();
$availableCars = [];
$availableCars = $result->fetchAll();
How can I solve this issue by making changes in this MySQL query alone, without altering the rest of my code?
Thank you.
If you are using PDO, you need to create a dynamic WHERE clause with parameters like in this example:
$whereClause = [];
$params = [];
if (!empty($bookedCarIds)) {
$whereClause[] = 'id NOT IN (?' . str_repeat(', ?', count($bookedCarIds) - 1) . ')';
$params = $bookedCarIds;
}
if (!empty($fromlocation)) {
$whereClause[] = 'location = ?';
$params[] = $fromlocation;
}
if (!empty($fromdate) && !empty($todate)) {
$whereClause[] = 'fromdate BETWEEN ? AND ?';
$params[] = $fromdate;
$params[] = $todate;
}
$whereClause = !empty($whereClause) ? 'WHERE ' . implode(' AND ', $whereClause) : '';
$result = $pdo->prepare("SELECT * FROM cars $whereClause");
$result->execute($params);
$availableCars = $result->fetchAll();
I am trying to create an array in $data, but it is not happening. I am using this code to make a day wise sale chart.
$data = array();
for ($i = 0; $i <= 10; $i++) {
$billdate = date('d-m-Y', strtotime("-$i day"));
$sqlQuery = "select sum(amount),bill_date from msr_bills WHERE bill_date='$billdate' ";
$result = mysqli_query($con, $sqlQuery);
$fetchamount = mysqli_fetch_row($result);
$sum = $fetchamount[0];
$data = new \stdClass();
$data->bill_date = $billdate;
$data->amount = $sum;
$report_JSON = json_encode($data);
echo $report_JSON.",";
}
You can merge your loop into one query, and then iterate over the results instead:
$data = array();
$billdate = date('Y-m-d', strtotime('-10 day'));
$sqlQuery = "SELECT bill_date, SUM(amount) AS amount
FROM msr_bills
WHERE bill_date >= '$billdate'
GROUP BY bill_date";
$result = mysqli_query($sqlQuery);
if ($result) {
while ($row = mysqli_fetch_assoc($result)) {
$data[] = (object)$row;
}
$report_JSON = json_encode($data);
echo $report_JSON;
}
Note that your date format is not compatible with MySQL dates, which are stored in Y-m-d format, and I have changed that in the code. If your bill_date column is actually a text field stored in d-m-Y format, you will need to convert it in the query like so:
$sqlQuery = "SELECT bill_date, SUM(amount) AS amount
FROM msr_bills
WHERE STR_TO_DATE(bill_date, '%d-%m-%Y') >= '$billdate'
GROUP BY bill_date";
Note also that you can in fact do the computation of $billdate internal to your SQL query using date arithmetic:
$sqlQuery = "SELECT bill_date, SUM(amount) AS amount
FROM msr_bills
WHERE STR_TO_DATE(bill_date, '%d-%m-%Y') >= CURDATE() - INTERVAL 10 DAY
GROUP BY bill_date";
And if you are running MySQL 8.0+, you can do the entire operation in MySQL:
$sqlQuery = "SELECT JSON_ARRAYAGG(data) AS data
FROM (SELECT JSON_OBJECT('bill_date', bill_date, 'amount', SUM(amount)) AS data
FROM msr_bills
WHERE bill_date >= CURDATE() - INTERVAL 10 DAY
GROUP BY bill_date) d";
$result = mysqli_query($sqlQuery);
if ($result) {
$row = mysqli_fetch_assoc($result);
$report_JSON = $row['data'];
echo $report_JSON;
}
Demo on dbfiddle
Put your echo outside loop. remove code $report_JSON = json_encode($data);
$respnseArr = array();
{
.
.
.
$respnseArr[] = $data;
}
echo json_encode($respnseArr);
I have this code as my function of getting the list, however with the ORDER BY code it doesnt work (doesn't return anything). How do i go about ordering it? I have looked at other peoples work on how o do it but i can't get it to work.
<?php
function getGenericList($conn, $limit) {
$sql = "SELECT * FROM `jobs_current` LIMIT ".$limit." ORDER BY `jobs_current`.`school` ASC";
$query = $conn->prepare($sql);
$query->execute();
$count = $query->rowCount();
if($count == 0){
return '<td class="td1"></td><td class="td2" style="color: red;">Sorry, there doesnt seem to be any results!</td><td class="td3"></td>';
}
$end = "";
foreach ($conn->query($sql) as $row) {
$end = $end.'<tr class="hoverOver"><td class="td1">'.$row['school'].'</td>';
$end = $end.'<td class="td2">'.$row['job_type'].'</td>';
$end = $end.'<td class="td3">'.$row['location'].'</td></tr>';
}return $end;
}
?>
Why doesn't it just return the rows in order defined? I generated the query using phpmyadmin so i don't understand why it doesnt work.
You query syntax is wrong, the correct way to write this is first ORDER and then LIMIT :
"SELECT * FROM `jobs_current` ORDER BY `jobs_current`.`school` ASC LIMIT ".$limit.""
Hey guys so I am having some trouble using the following:
for ($i = 0; $i < count($noncompUsername); $i++)
{
$tsql ="SELECT firstname,lastname,email,phone,statuschangedate FROM csvdata WHERE username = :username ORDER BY statuschangedate";
$tgetmeminfo=$DBH->prepare($tsql);
$tgetmeminfo->execute(array(':username' => $noncompUsername[$i]));
while ($trow = $tgetmeminfo->fetch(PDO::FETCH_ASSOC)){
$csvFirst = $trow['firstname'];
$csvLast = $trow['lastname'];
$csvEmail = $trow['email'];
$csvPhone = $trow['phone'];
$csvDate = $trow['statuschangedate'];
$timediff = strtotime($date) - strtotime($csvDate);
$timediff = floor($timediff/86400);
$sql ="SELECT MailingAdrs FROM insuranceverificationdisclaimer WHERE TraineeUsername = :tusername";
$getmeminfo=$DBH->prepare($sql);
$getmeminfo->execute(array(':tusername' => $noncompUsername[$i]));
while ($row = $getmeminfo->fetch(PDO::FETCH_ASSOC)){
$csvAddrs = $row['MailingAdrs'];
$change = 1;
}
if($change != 1)
{
$csvAddrs = "No address";
}
$change = 0;
echo "$timediff, $csvFirst $csvLast, $csvEmail, $csvPhone, $csvAddrs";
}
echo "
<br>
";
}
Now this works but the part I want to point out is the $tsql ="SELECT firstname,lastname,email,phone,statuschangedate FROM csvdata WHERE username = :username ORDER BY statuschangedate"; - now when I do this and get the integer of the statuschangedate to the current date and print it out as an integer, it is not ordered properly based on the date.
So I need to get this to order by the oldest date on top and as follows...
Thank you!
David
Order the date in descending order (using DESC):
... ORDER BY statuschangedate DESC
If you want to order based on $timediff you should change the ORDER clause to this:
ORDER BY DATEDIFF(:date, statuschangedate)
Granted, this should actually give the same ordering you already had, but you could at least use this expression to save some processing in PHP itself :)
I have the following code and all of the search functions work except for the title field. So I can search by genre, date, location etc... but not by title. When attempting to search by title nothing is returned at all. Can anyone help me with this?
Also, is there a more efficient way to count all the fields before limiting it for use in pagination later on?
$today = date("Y-m-d");
$query = "SELECT * FROM TABLE_NAME WHERE Date >= '$today'";
$bind = Array();
if ($_GET["Title"] && $_GET["Title"] != "") {
$query .= " and Title like %?%";
$bind['Title'] = $_GET['Title'];
}
if ($_GET["Genre"] && $_GET["Genre"] != "") {
$query .= " and Genre like %?%";
$bind['Genre'] = $_GET['Genre'];
}
if ($_GET["Location"] && $_GET["Location"] != "") {
$query .= " and Location like %?%";
$bind['Location'] = $_GET['Location'];
}
if ($_GET["Date"] && $_GET["Date"] != "") {
$query .= " and Date = %?%";
$bind['Date'] = $_GET['Date'];
}
$stmt = $db->prepare($query);
$stmt->execute($bind);
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
$num = count($rows);
$query .= " ORDER BY Date LIMIT $limit, 9";
$stmt = $db->prepare($query);
$stmt->execute($bind);
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
Edit: After everyone's help I thought I would post my now revised code for future reference. It turns out the other fields were not working, but instead due to the if statement all this was nested in the code simply wasn't being executed.
$today = date("Y-m-d");
$query = "SELECT * FROM TABLE_NAME WHERE Date >= '$today'";
$countq = "SELECT count(*) FROM TABLE_NAME WHERE Date >= '$today'";
$bind = Array();
if ($_GET["Title"] && $_GET["Title"] != "") {
$query .= " and Title like :title";
$countq .= " and Title like :title";
$bind[':title'] = "%{$_GET['Title']}%";
}
if ($_GET["Genre"] && $_GET["Genre"] != "") {
$query .= " and Genre like :genre";
$countq .= " and Genre like :genre";
$bind[':genre'] = "%{$_GET['Genre']}%";
}
if ($_GET["Location"] && $_GET["Location"] != "") {
$query .= " and Location like :loc";
$countq .= " and Location like :loc";
$bind[':loc'] = "%{$_GET['Location']}%";
}
if ($_GET["Date"] && $_GET["Date"] != "") {
$query .= " and Date = :date";
$countq .= " and Date = :date";
$bind[':date'] = "{$_GET['Date']}";
}
$stmt = $db->prepare($countq);
$stmt->execute($bind);
$rows = $stmt->fetchAll();
$num = count($rows);
$query .= " ORDER BY Date LIMIT $limit, 9";
$stmt = $db->prepare($query);
$stmt->execute($bind);
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
all of the search functions work
With the given query it is not true
From PDO tag wiki:
placeholders cannot represent an arbitrary part of the query, but a complete data literal only. Neither part of literal, nor whatever complex expression or a syntax keyword can be substituted with prepared statement.
Prepare FULL literal first: $name = "%$name%"; and then bind it.
As for the "more" efficient method for pagination - yes, oh yes.
With your current way of counting data you don't actually need other queries. as you have ALL the data already and can paginate it as well.
But of course it will pollute all the memory soon. So, if you want to get a count of rows from database, get the very count: run the same query but instead of SELECT * make it "SELECT count(*)
There are not any errors returned, that's why I am so confused
From PDO tag wiki again:
It is essential to set ERRMODE_EXCEPTION as a connection option as it will let PDO throw exceptions on connection errors. And this mode is the only reliable way to handle PDO errors.