i want to use orderby clause in the prepared statement.
following is my query
$stmt = $connect->prepare("SELECT send_stamp,id,receiverid, message, time, status,sentby FROM `chat` WHERE cust_id=?");
$stmt->bind_param('i', $cust_id);
$result=$stmt->execute();
Now where do i add order by(asc) in this query to sort it by date or id.
Please help
You do it like this:
$stmt = $connect->prepare("SELECT send_stamp,id,receiverid, message, time, status,sentby FROM `chat` WHERE cust_id = ? ORDER BY id ASC");
$stmt->bind_param('i', $cust_id);
$result=$stmt->execute();
As in normal SQL query: at the end of query:
$stmt = $connect->prepare(
"SELECT
send_stamp,id,receiverid, message, time, status, sentby
FROM `chat`
WHERE cust_id=?
ORDER BY id DESC"
);
$stmt->bind_param('i', $cust_id);
$result=$stmt->execute();
You just need to add at the end of query, following is an example in which I added ascending order clause.
$stmt = $connect->prepare(
"SELECT
send_stamp,id,receiverid, message, time, status, sentby
FROM `chat`
WHERE cust_id=?
ORDER BY id ASC"
);
$stmt->bind_param('i', $cust_id);
$result=$stmt->execute();
The above query will return the record with ascending order of id, since we are using order clause on id.
Normally in mysql order by is used at the end of the statement. like
SELECT send_stamp,id,receiverid, message, time, status,sentby FROM `chat` WHERE cust_id=? order by id
you can order by id,name or anything you want just write the name of that field.
$stmt = $connect->prepare("SELECT send_stamp,id,receiverid, message, time, status,sentby FROM `chat` WHERE cust_id=? ORDER BY date ASC");
Related
I want to update the stock quantities of my products in the DB after a purchase.
My code already works fine, but I want to know if there is a best way to do, with only one SQL statement?
// All the product in the member's cart
if ($stmt = $conn->prepare("SELECT product_id, quantity FROM tbl_cart WHERE member_id = ?")) {
$stmt->bind_param("i", $memberId);
$stmt->execute();
$result = $stmt->get_result();
$stmt->close();
$cartItem = $result->fetch_all(MYSQLI_ASSOC);
// Set the quantity after purchase
foreach ($cartItem as $key => $item) {
$stmt = $conn->prepare("UPDATE tbl_product SET stock = stock-? WHERE id = ?");
$stmt->bind_param("ii", $item['quantity'], $item['product_id']);
$stmt->execute();
$stmt->close();
}
}
I don't know if this is better way but you may try this Sql statement.
UPDATE tbl_product
SET stock = stock - ( SELECT quantity FROM tbl_cart
WHERE product_id = tbl_product.id AND member_id = ? )
WHERE id IN ( SELECT product_id FROM tbl_cart WHERE member_id = ? )
You can try using trigger function. Look here: mysql after insert trigger which updates another table's column
You could update other column when order is placed.
In my opinion, the trigger function is not the best option, because it will move logic to other place.
But it is one of the alternative, that you ask for.
That's the solution I found. I think it's just more clean.
$stmt = $conn->prepare("UPDATE tbl_product AS p
JOIN tbl_cart AS c
ON p.id = c.product_id
SET p.stock = p.stock-c.quantity
WHERE c.member_id = ?");
$stmt->bind_param("i", $memberId);
$stmt->execute();
$stmt->close();
Thank you for your help.
I have simple prepared statement, and i can't find solution to bind list of id's, so as you can see in first statement i get all ids that i need, and in next statement i need to put all those ids into IN clause, but i'm not able to do it, any suggestions how and what is best way to do it ?
$stmt = $mysqli->prepare("SELECT id FROM user WHERE groupId = ? ORDER BY id LIMIT ? OFFSET ?");
$stmt->bind_param("iii", $args['groupId'], $pageSize, $offset);
$stmt->execute();
$stmt->bind_result($id);
$userIds= array();
while ($stmt->fetch()) {
$userIds[] = $id;
}
$stmt= $mysqli->prepare("SELECT a.id as attendantId, a.firstName, a.lastName, c.id as caringId, c.startDate, c.endDate FROM attendant a LEFT JOIN caring c ON c.attendantId = a.id WHERE a.id IN (?)");
$stmt->bind_param('i', $userIds);
$stmt->bind_param('i', implode(',', $userIds));
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.
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();
Im having an invalid parameter error but I guess that I have the right number of parameter.
Does anyone see the opposite here?
Im getting this error:
PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens in $readNews->execute();
if(isset($_POST['search']))
{
$search = $_POST['search'];
$readNews = $pdo->prepare("SELECT * FROM news WHERE title LIKE ? ORDER BY date DESC LIMIT ?, ?");
$readNews->bindValue(1, $search);
$readNews->bindValue(1, $begin,PDO::PARAM_INT);
$readNews->bindValue(2, $max,PDO::PARAM_INT);
}
else
{
$readNews = $pdo->prepare("SELECT * FROM news ORDER BY date DESC LIMIT ?, ?");
$readNews->bindValue(1, $begin,PDO::PARAM_INT);
$readNews->bindValue(2, $max,PDO::PARAM_INT);
}
$readNews->execute();
You have three parameters yet you assign a value to index 1 twice. Try this...
$readNews->bindValue(1, $search);
$readNews->bindValue(2, $begin,PDO::PARAM_INT);
$readNews->bindValue(3, $max,PDO::PARAM_INT);
I'm guessing you may want to wrap some wildcard characters around the $search value too. Try this...
$readNews->bindValue(1, "%$search%");
... or use CONCAT in your query...
WHERE title LIKE CONCAT('%', ?, '%')
Your query should also use WHERE instead of AND...
SELECT * FROM news WHERE title LIKE ? ORDER BY date DESC LIMIT ?, ?"
I would probably simplify this by using named placeholders to remove some of the duplication. In total, this...
if (isset($_POST['search'])) {
$stmt = $pdo->prepare("SELECT * FROM news WHERE title LIKE CONCAT('%', :search, '%') ORDER BY date DESC LIMIT :begin, :max");
$stmt->bindParam(':search', $_POST['search']);
} else {
$stmt = $pdo->prepare('SELECT * FROM news ORDER BY date DESC LIMIT :begin, :max');
}
$stmt->bindParam(':begin', $begin, PDO::PARAM_INT);
$stmt->bindParam(':max', $max, PDO::PARAM_INT);
$stmt->execute();