PDO SQL Query Not Limiting - php

I'm trying to get results from a query to the database but the LIMIT isn't working. When I put LIMIT 10 it returns no results. Am I missing something here?
Here is my code. I'm trying to figure out what the reason is for this strange behavior.
$username = "derek";
$query = $conn->prepare('SELECT * FROM notifications WHERE (needs=:username OR worker=:username1) ORDER BY CASE WHEN needs=:username2 THEN needsread ELSE workerread END, time DESC LIMIT 10');
$query->bindParam(':username', $username);
$query->bindParam(':username1', $username);
$query->bindParam(':username2', $username);
$query->execute();

Ended up being something with my if statements. I was getting the results but after filtering through my if statements the 10 results I wanted to show shouldn't have shown. So after fixing my query to the database it worked. Here's my query:
$workneed = "workneed";
$follow="follow";
$query = $conn->prepare('SELECT * FROM notifications WHERE CASE WHEN needs=:username THEN type=:workneed END OR CASE WHEN worker=:username THEN type=:follow END ORDER BY CASE WHEN needs=:username THEN needsread ELSE workerread END, time DESC LIMIT 10');
$query->bindParam(':username', $username);
$query->bindParam(':workneed', $workneed);
$query->bindParam(':follow', $follow);
$query->execute();

Related

PHP PDO Prepared Statements with Where IN Clause

This is my PHP PDO Code
$stmt = $conn->prepare("SELECT * FROM TABLE
WHERE tag1 IN ('$tag1','$tag2') $andor tag2 IN ('$tag1','$tag2 ') ORDER BY $sort DESC LIMIT $limit OFFSET $start");
// Then fire it up
$stmt->execute();
// Pick up the result as an array
$result = $stmt->fetchAll();
// Now you run through this array in many ways, for example
I am trying to convert it into prepared statements, but I really don't understand, how it will work. I tried a lot of things from Google, but nothing worked.
$stmt = $conn->prepare("SELECT * FROM table WHERE tag1=? OR tag1=? AND tag2=? OR tag2=? ORDER BY id DESC LIMIT 15,10");
$stmt->execute(array($tag1, $tag2, $tag1, $tag2));
$result = $stmt->fetch(PDO::FETCH_ASSOC);
I hope it works.

Using sql queries in a loop

I have a query in my foreach loop and I feel I should not be doing this.
How would I go about improving this code(Here I select Messages):
try{
$sql="
SELECT * FROM messages
WHERE workspace_id=:project_id
ORDER BY message_created DESC
LIMIT 20
OFFSET :offset";
$stmt=$db->prepare($sql);
$stmt->bindValue(':project_id', $project_id, PDO::PARAM_INT);
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$stmt->execute();
$messages=$stmt->fetchAll(PDO::FETCH_ASSOC);
}catch(Exception $e){echo $e->getMessage();}
Now I need users first and last name from table users. I couldn't think of another way but putting it in a loop.
foreach($messages as $row){
echo $row['message'];
$sql= "SELECT first_name, last_name FROM users
WHERE user_id=:id
LIMIT 1";
$stmt=$db->prepare($sql);
$stmt->bindValue(':id', $row['sent_by']);
$stmt->execute();
$user=$stmt->fetch(PDO::FETCH_ASSOC);
echo $user['first_name'] . " " . substr($user['last_name'],0,1) . ".";
}
This code works just the way I want it to but it doesn't look like it is supposed to be done this way.
Can anyone help me out here
You could do a SQL join to completely avoid the foreach loop.
try{
$sql="
SELECT messages.*, users.first_name, users.last_name
FROM messages join users on messages.user_id = users.user_id
WHERE workspace_id=:project_id
ORDER BY message_created DESC
LIMIT 20
OFFSET :offset";
$stmt=$db->prepare($sql);
$stmt->bindValue(':project_id', $project_id, PDO::PARAM_INT);
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$stmt->execute();
$messages=$stmt->fetchAll(PDO::FETCH_ASSOC);
}catch(Exception $e){echo $e->getMessage();}
Note: I am assuming messages table has user id and is stored in "user_id" field. Change the field name accordingly, if it is different.

Get Date Difference

I want to get the difference between two date in my query. I tried using multiple select statement but it's not working
Here's my code
$tbl_name = "myTable";
$setDay = "10";
$stmt = $pdo->query("SELECT * (
SELECT due_date,
date_paid,
DATEDIFF(due_date, date_paid) as date_interval)
FROM $tbl_name
WHERE DATEDIFF(due_date, date_paid) <= $setDay
ORDER BY trans_id DESC LIMIT $start, $limit");
$stmt->execute();
Thanks
It is important to develop you MySQL queries and perfect them outside the context of PHP code first, then integrate the query once you have it working the way you need it to in a MySQL client application like MySQL Workbench, PHPMyAdmin, etc.
In your query, the outer SELECT is not needed, and the inner query itself looks almost correct, but it is the way you attempt to execute it with PDO that is faulty.
SELECT
due_date,
date_paid,
DATEDIFF(due_date, date_paid) as date_interval
FROM $tbl_name
WHERE
DATEDIFF(due_date, date_paid) <= $setDay
ORDER BY trans_id DESC
LIMIT $start, $limit
Now to execute it in PDO, you should be using prepare()/bindParam()/execute() to create a prepared statement, bind in parameters, and execute it with those parameters (you cannot bind the table name though - that must remain a variable). In your current code, you have a mixup of the the PDO::query() method used for simple static queries and the PDOStatement::execute() method which is used to execute a prepared statement. You should be using the prepared statement method, rather than query().
// Setup the statement with named parameters like :setDay
$sql = "
SELECT
due_date,
date_paid,
DATEDIFF(due_date, date_paid) as date_interval
FROM $tbl_name
WHERE
DATEDIFF(due_date, date_paid) <= :setDay
ORDER BY trans_id DESC
LIMIT :start, :limit
";
// Make PDO throw useful errors on failure
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Prepare the statement
$stmt = $pdo->prepare($sql);
// Bind your 3 parameters and execute it
$stmt->bindParam(':setDay', $setDay, PDO::PARAM_INT);
$stmt->bindParam(':start', $start, PDO::PARAM_INT);
$stmt->bindParam(':limit', $limit, PDO::PARAM_INT);
$stmt->execute();
// Fetch your rows returned from the query
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Do something with them
print_r($rows);
I always recommend spending time with this PDO tutorial for MySQL developers which places PDO's usage in context of the old mysql_*() API you may already be familiar with.
Try this,
SELECT * , (select (DATEDIFF(due_date,date_paid)) AS date_interval) FROM $tbl_name
Use this to find the date defference,
$diff=date_diff($date1,$date2);

Whats wrong with my PDO mysql query [duplicate]

This question already has an answer here:
Invalid Parameter Number. Parameter not defined
(1 answer)
Closed 8 years ago.
Here is my code
$sql3= "select *
from comments
where status=:status
limit=:limit
offset=:offset
order by time desc";
$query3= $pdo->prepare($sql3);
$query3->bindValue(":status",'n');
$query3->bindValue(":limit",$per_page);
$query3->bindValue(":offest",$offset);
$query3->execute();
$comments=$query3->fetchall();
Here comments is my table name status and time is two column in my table . Whenever I run this code , It shows a warning
Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: parameter was not defined in E:\XAMPP\htdocs\parlament\user\logged_in_area.php
What does this mean ?
The answer depends of what are limit and offset.
If they're columns names...
You can't use these reserved keywords for column names without backticks
You need to add a AND / OR operator between your lines
$sql3= "select *
from comments
where status=:status
and `limit`=:limit
and `offset`=:offset
order by time desc";
$query3= $pdo->prepare($sql3);
$query3->bindValue(":status", 'n');
$query3->bindValue(":limit", $per_page);
$query3->bindValue(":offest", $offset);
$query3->execute();
$comments=$query3->fetchall();
If they're keywords...
The syntax is LIMIT <n>, not LIMIT = <n> (same for OFFSET)
It better to specify their type with PDO::PARAM_INT (same for OFFSET)
ORDER BY must be added before LIMIT and OFFSET
$sql3= "select *
from comments
where status=:status
order by time desc
limit :limit
offset :offset";
$query3= $pdo->prepare($sql3);
$query3->bindValue(":status", 'n');
$query3->bindValue(":limit", (int)$per_page, PDO::PARAM_INT);
$query3->bindValue(":offset", (int)$offset, PDO::PARAM_INT);
$query3->execute();
$comments=$query3->fetchall();
Adding my answer because nobody has mentioned this specific part yet...
MySQL is very picky about the data type of LIMIT parameters. You pretty much need to use bindParam(':limit', $per_page, PDO::PARAM_INT). I assume the same for OFFSET.
So, in summary
// because E_WARNING level errors are insufficient
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $pdo->prepare('SELECT * FROM `comments` WHERE `status` = :status ORDER BY `time` DESC LIMIT :limit OFFSET :offset');
$stmt->bindValue(':status', 'n');
$stmt->bindParam(':limit', $per_page, PDO::PARAM_INT);
$stmt->bindParam(':offset', $offset, PDO::PARAM_INT); // spelt "offset"
$stmt->execute();
$comments = $stmt->fetchAll(PDO::FETCH_ASSOC);
Try this->
$sql3= "select *
from comments
where status = ?
limit ?
offset ?
order by time desc";
$query3= $pdo->prepare($sql3);
$query3->execute(array('n',$per_page,$offset));
$comments=$query3->fetchall();
Not sure about that but I think that PDO::bindValue / bindParam works with variable references. You cannot set a static value as parameter.
Try to replace
$query3->bindValue(":status",'n');
by
$n_value = 'n';
$query3->bindValue(":status",$n_value);
You also forgot the "AND" Keyword between your conditions
You're missing the AND or OR keyword in statement. Also, LIMIT is a reserved keyword, you'll need to backtick it or rename it to something else if you don't want to do that.
$sql3= "select *
from comments
where status = ?
limit= ?
offset= ?
order by time desc";
$query3= $pdo->prepare($sql3);
$query3->bindValue(1,'n');
$query3->bindValue(2,$per_page);
$query3->bindValue(3,$offset);
$query3->execute();
$comments=$query3->fetchall();

how to do change this query into a prepared statement?

Right, so i'm still getting my head around prepared statements and every time i think, yeah i've got it, a new query comes along and i'm thinking Hmmmm i would i set that up?
So here we go, i have a query that pulls records from a database based on a date and orders them by said date. The records it finds are based on a year and month value and the query looks like this:
$getresults = mysql_query(" SELECT * FROM `results` WHERE `date` LIKE '2012-$monthid%' ORDER BY date ");
I already have basic prepared statement for getting a users record from my database:
$query = "SELECT *
FROM results
WHERE date = ?
LIMIT 1";
if($stmt = $this->conn->prepare($query))
{
$stmt->bind_param('s', $date);
$stmt->execute();
if($stmt->fetch())
{
$stmt->close();
return true;
}
else
return false;
}
How would i change this to make it more like the first query?
Thanks for the help.
One idea would be to filter by year and month in separate parts of the WHERE clause:
$query = "SELECT * FROM results WHERE YEAR(date) = 2012 AND MONTH(date) = ? ORDER BY date";
if ($stmt = $this->conn->prepare($query)) {
$stmt->bind_param('i', $monthid);
...
}

Categories