How can I get a count of the number of affected rows when I'm deleting multiple rows in PDO? This is the technique I'm using to delete multiple rows:
$selected = $_POST['checkbox'];
$N = count($selected);
for ($i = 0; $i < $N; $i++) {
$result = $dbh->prepare('DELETE FROM users WHERE id= :id');
$result->bindParam(':id', $selected[$i], PDO::PARAM_INT);
$result->execute();
}
I tried this, but it always returned 1:
$deleted = $result->rowCount();
if ($deleted) {
echo $deleted.' was deleted.';
}
You're running a loop, so each call is deleting 1; you need to add a counter.
So add:
$deleted += $result->rowCount();
inside the loop
and then outside:
if ($deleted) {
echo $deleted.' was deleted.';
}
If the id field is unique, then that statement could affect at most 1 row. However you are preparing a new statement and executing it in a loop. You should try adding up how many you delete.
$deleted = 0;
for ($i = 0; $i < $N; $i++) {
$result = $dbh->prepare('DELETE FROM users WHERE id= :id');
$result->bindParam(':id', $selected[$i], PDO::PARAM_INT);
$result->execute();
$deleted = $deleted + $result->rowCount();
}
echo $deleted.' was deleted.';
Here's a way to do it in 1 delete instead of running multiple deletes.
This way rowCount() will show the actual results deleted.
$selected = $_POST['checkbox'];
$placeholder = array();
$values = array();
foreach ($selected as $id) {
$placeholder[] = ":".$id;
$values[":".$id] = $id;
}
$sql = "Delete FROM users WHERE id IN (".implode(', ',$placeholder).") ";
$result = $dbh->prepare($sql);
$result->execute($values);
$deleted = $result->rowCount();
if ($deleted>0) {
echo $deleted.' was deleted.';
}
Related
I want to assign same quantity of work by each worker available in php.
This is my array of available worker:
if (!isset($array_worker)){
$array_worker = array();
}
$stmt = $dbh->prepare("SELECT username
FROM group_members
WHERE grp_id = :grp_id
AND statut > 0
AND specification != 2");
$stmt->bindValue(':grp_id', $grp_id);
$stmt->execute();
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($data as $key => $value){
if (!in_array($value['username'], $array_worker)){
array_push($array_worker, $value['username']);
}
}
This array_worker return 2 entries
That is what I have try
$n = 0;
for ($i = 0; $i < count_worknotdone($grp_id); $i++) {
if ($n >= count($array_worker)){
$n = 0;
}
$stmt = $dbh->prepare("UPDATE work
SET worker = :worker
WHERE grp_id = :grp_id
AND worker IS NULL");
$stmt->bindValue(':worker ', $array_worker[$n]);
$stmt->bindValue(':grp_id', $grp_id);
$stmt->execute();
$n++;
}
but that assign only the first worker for each work..
What I want for example if we have 2 workers available and 4 work not done
We assign 2 work for each workers.
Thanks you
if (!isset($array_worker)){
$array_worker = array();
}
if (!isset($array_id)){
$array_id = array();
}
$stmt = $dbh->prepare("SELECT username FROM group_members WHERE grp_id = :grp_id AND statut > 0 AND specification != 2");
$stmt->bindValue(':grp_id', $grp_id);
$stmt->execute();
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($data as $key => $value){
if (!in_array($value['username'], $array_worker)){
array_push($array_worker, $value['username']);
}
}
$stmt = $dbh->prepare("SELECT id FROM work WHERE grp_id = :grp_id AND statut < 1 AND worker IS NULL");
$stmt->bindValue(':grp_id', $grp_id);
$stmt->execute();
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($data as $key => $value){
if (!in_array($value['id'], $array_id)){
array_push($array_id, $value['id']);
}
}
$n = 0;
for ($i = 0; $i < count($array_id); $i++) {
if ($n >= count($array_worker)){
$n = 0;
}
$stmt = $dbh->prepare("UPDATE work SET worker = :worker WHERE id = :id AND grp_id = :grp_id AND worker IS NULL");
$stmt->bindValue(':id', $array_id[$i]);
$stmt->bindValue(':worker', $array_worker[$n]);
$stmt->bindValue(':grp_id', $grp_id);
$stmt->execute();
$n++;
}
I have done what I want by doing that, that for sure can be improve but its working..
Apparently, the num_rows property does not work in PDO as it would with mysqli.
Normally, with mysqli, my code would look like this:
<?php
$conn = new mysqli('127.0.0.1','root','mypassword','mydbname');
if($conn->connect_errno){
die("Sorry, could not connect.");
}
$id = 1;
$qry = "SELECT * FROM customers WHERE id = ?";
$getCustomers = $conn->prepare($qry);
$getCustomers->bind_param("i",$id);
$getCustomers->execute();
$result = $getCustomers->get_result();
$count = $result->num_rows;
if($count == 0){
echo "Sorry, there are no results";
}else{
while($row = $result->fetch_object()){
echo $row->id;
echo $row->fname;
echo $row->lname;
echo $row->entry_date;
}
}
?>
How do I create the equivalent with PDO? Here is what I have tried so far:
<?php
try{
$conn = new PDO('mysql:host=127.0.0.1;dbname=mydbname','root','mypassword');
}catch(PDOException $e){
echo $e;
}
$id = 1;
$qry = $conn->prepare("SELECT * FROM customers WHERE id = :id");
$qry->execute([':id'=>$id]);
$rows = $qry->fetchAll(PDO::FETCH_OBJ);
$count = count($rows);
if($count == 0){
echo "Sorry, there are no results for your criteria";
}else{
for($i = 0; $i < $count; $i++){
echo $rows->fname;
}
}
?>
Yeah isn't PDO great ;p no need to count rows when you have already got them.
To loop over your result as you have an array.
Change:
for ($i = 0; $i < $count; $i++){
echo $rows->fname;
}
To:
for ($i = 0; $i < $count; $i++){
echo $rows[$i]->fname;
}
Or better just use a foreach.
foreach ($rows as $row) {
echo $row->fname;
}
The statement
fetchAll(PDO::FETCH_OBJ) returns an array containing all of the result set rows as described here. To get the size of the array use sizeof($count). That should give you the size of the array.
To answer your question specifically. You can use rowCount() to retrieve the number of rows in a result:
$qry = $conn->prepare("SELECT * FROM customers WHERE id = :id");
$qry->execute([':id'=>$id]);
$count = $qry->rowCount();
$rows = $qry->fetchAll(PDO::FETCH_ASSOC); //my personal preference
for($i=0; $i < $count; $i++) {
echo $rows[$i]['fname'];
}
To more closely replicate your mysqli code:
while($row = $qry->fetch(PDO::FETCH_OBJ) {
echo $row->fname;
}
Of course, you should always check $conn->errorCode() after each database execution to ensure something go sideways on you.
UPDATE:
As Lawrence points out, rowCount() does not work with MS SQL Server. An alternative in that case is to use fetchAll() and count().
I am completely stumped how to do this. I want to perform a function per batch of 100 mysql results.
$stmt=$db->prepare("SELECT count(user) AS cnt, user FROM table");
$stmt->execute();
$row = $stmt->fetchAll();
foreach ($row AS $row) {
$user .= $row['user'];
}
function($user);
The trouble is I can't figure out how to stop the loop each 100, perform the function, then continue again until there are no more results.
$stmt=$db->query("SELECT user FROM table");
$i = 1;
foreach ($stmt as $row) {
$user .= $row['user'];
if ($i++ == 100) {
function($user);
$i = 1;
}
}
function($user);
Having a bit of an issue with my php code..
$stmt = $db->prepare("SELECT * FROM mytable WHERE TheGroup = :SearchName ORDER BY TheTime DESC");
$stmt->bindParam(':SearchName', $request, PDO::PARAM_STR);
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
$count = count($result);
for ($i = 0; $i < $count; $i++) {
$mTheAvatar = $result[$i]->TheAvatar;
$mTheDirection= $result[$i]->TheDirection;
$mTheGroup = $result[$i]->TheGroup;
$mTheMedia = $result[$i]->TheMedia;
$mTheMessage = $result[$i]->TheMessage;
$mTheSenderName= $result[$i]->TheSenderName;
$mTheThumbImage = $result[$i]->TheThumbImage;
$mTheTime = $result[$i]->TheTime;
$mTheMediaExtension = $result[$i]->TheMediaExtension;
echo "hello";
echo $mTheAvatar;
echo " <- this is avatar";
}
If I do a Var_dump() I see the data being requested without a problem.
If I echo the variables , they are blank..
I have triple checked that the table column names are correct..
the $mTheAvater is a pic in table, if that gives a possible clue, but the rest are blank as well so not sure what is up?!?
You can test:
$mTheAvatar = $result[$i]['TheAvatar'];
As I know in the FETCH_ASSOC it returns data in above structure.
You are trying to read them as if they are objects, but PDOStatement::fetchAll returns an array, so your code should look like:
for ($i = 0; $i < $count; $i++) {
$mTheAvatar = $result[$i]['TheAvatar'];
$mTheDirection= $result[$i]['TheDirection'];
.
.
.
.
echo "hello";
echo $mTheAvatar;
echo " <- this is avatar";
}
If you want to handle objects, you should use PDOStatement::fetchObject
This should be better - 1) it's using foreach; 2) unset(); 3) different structure
$stmt = $db->prepare("SELECT * FROM mytable WHERE TheGroup = :SearchName ORDER BY TheTime DESC");
$stmt->bindParam(':SearchName', $request, PDO::PARAM_STR);
$stmt->execute();
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
if($results){
foreach($results as $result_data) {
echo $result_data['TheAvatar'];
echo $result_data['TheDirection'];
//and so on
unset($result_data);
}
}
else{
echo 'Empty';
}
Ok, I thought I had this, but I can't see why it's not working...
I have a SELECT with a variable table, hence my columns (bind_result) is going to be variable.
I need to adjust for any number of columns coming back, and fetch as an associated array, since there will be multiple rows coming back:
// Get table data
$mysqli = new mysqli('host','login','passwd','db');
if ($mysqli->connect_errno()) { $errors .= "<br>Cannot connect: ".$mysqli->connect_error()); }
$stmt = $mysqli->prepare("SELECT * FROM ?");
$stmt->bind_param('s', $table);
$stmt->execute();
// Get bind result columns
$fields = array();
// Loop through columns, build bind results
for ($i=0; $i < count($columns); $i++) {
$fields[$i] = ${'col'.$i};
}
// Bind Results
call_user_func_array(array($stmt,'bind_result'),$fields);
// Fetch Results
$i = 0;
while ($stmt->fetch()) {
$results[$i] = array();
foreach($fields as $k => $v)
$results[$i][$k] = $v;
$i++;
}
// close statement
$stmt->close();
Any thoughts are greatly appreciated ^_^
EDIT: New code:
$mysqli = new mysqli('host','login','passwd','db');
if ($mysqli->connect_errno)) { $errors .= "<br>Cannot connect: ".$mysqli->connect_error()); }
$stmt = "SELECT * FROM ".$table;
if ($query = $mysqli->query($stmt)) {
$results = array();
while ($result = $query->fetch_assoc()) {
$results[] = $result;
}
$query->free();
}
$mysqli->close();
You can not bind the table name. Bind_param accept the column name and its datatype.
To use the table name dynamically use the below code:
$stmt = $mysqli->prepare("SELECT * FROM ".$table);