Fetch number of affected rows and last inserted ID using PDO statement - php

How can I display the numbers of affected rows in this:
$sql = $conn->prepare ("UPDATE countries SET country=:country");
$sql->bindValue(":country", "blablaa");
$sql->execute();
And how can I show the last inserted ID with this:
$sql = $conn->prepare ("INSERT INTO countries (country) VALUES (:country)");
$sql->bindValue(":country", "test");
$sql->execute();
echo $sql->lastInsertId(); // id of last inserted
I tried, but am receiving an error call to undefined method PDO::lastInsertId()

I think this can help you:
PDOStatement::rowCount()
returns the number of rows affected by the last DELETE, INSERT, or UPDATE statement executed by the corresponding PDOStatement object.
http://php.net/manual/en/pdostatement.rowcount.php

$sql->lastInsertId();
Needs to be replaced with
$dbh->lastInsertId();
Where $dbh is your PDO object.
See here for more information.
exec returns the number of affected rows, execute only returns a true or false value.

Related

How do I get a count on inserted rows for INSERT query with nested SELECT? No luck with affected_rows, result_id, num_rows

The INSERT statement with SELECT in VALUES:
$stmt = $db->prepare("INSERT INTO weld_reference(weld_id,report_id) VALUES ((SELECT w.id FROM welds w WHERE w.weld_number=?),?)")
The below code loops through an array of user submited strings ($welds) and tries insert its ID into table weld_reference if it exists in table welds.
$stmt->bind_param("si",$weld_number,$_POST['report_id']);
foreach($welds as $weld_number){
if($stmt->execute() and $stmt->num_rows){
++$insert_count;
}
}
I don't want to do another query to see if the row exists, I was hoping that I could get the number of rows or success of the INSERT after each $stmt->execute().
However, $stmt->affected_rows, and $stmt->insert_id always returns 1 and
$stmt->num_rows always returns 0 whether a row was inserted or not.
How can I get a read on this and see if a row has been inserted to send an accurate feedback message to the user?
How do you check the value of $stmt->insert_id? Because it should return you "Get the ID generated from the previous INSERT operation". If ou only ($evaluate) it it will return true (as 1)
The way i do it is i store the id's in an array so i can have a nice list of what has been inserted.
$stmt->bind_param("si",$weld_number,$_POST['report_id']);
foreach($welds as $weld_number){
if($stmt->execute()){
$insertedId[]=$stmt->insert_id;
}
}
echo count($insertedId);
Or since an id would logicaly never be empty you could do
$stmt->bind_param("si",$weld_number,$_POST['report_id']);
foreach($welds as $weld_number){
if($stmt->execute() && !empty($stmt->insert_id)){
$insert_count++;
// ++$insert_count; //unaware of this syntax -.-
}
}

PHP check if MYSQL query was an insert or update

I have a simple MYSQL query:
INSERT INTO table (col1,col2) VALUES ('1','2')
ON DUPLICATE KEY UPDATE col1 = '1', col2 = '2'
I use PHP PDO statements to query the database. Is there a way to know if the query executed resulted into a new inserted row or an existing was updated?
One way to do so is to get the number of rows before executing the query, then get the number of rows after executing the query, if they're not equal, it means a new row was inserted and if they are equal, it means a row was updated.
$sql = "SHOW TABLE STATUS LIKE 'TABLE_NAME'";
$stmt = $pdo->prepare($sql);
$stmt->execute();
$row = $stmt->fetch();
$number_of_rows_before = $row['Rows'];
// Do your query here, afterwards
$stmt = $pdo->prepare($sql);
$stmt->execute();
$row = $stmt->fetch();
$number_of_rows_after = $row['Rows'];
// If condition
if($number_of_rows_before == $number_of_rows_after) // Update was executed
else // a new row was inserted.
Just use mysqli_affected_rows,it returns the number of rows affected by the last INSERT, UPDATE, REPLACE or DELETE query.
From PHP documentation:
In the case of "INSERT ... ON DUPLICATE KEY UPDATE" queries, the return value will be 1 if an insert was performed, or 2 for an update of an existing row.
see https://www.php.net/manual/en/function.mysql-affected-rows.php
From Mysql manual:
"With ON DUPLICATE KEY UPDATE, the affected-rows value per row is 1 if
the row is inserted as a new row and 2 if an existing row is updated."
See: http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
This is the most reliable way to do it.
maybe you put the answer right into the query like:
INSERT INTO table (col1,col2, col_type) VALUES ('1','2','inserted')
ON DUPLICATE KEY UPDATE col1 = '1', col2 = '2', col_type = 'updated'

mysql insert ignore, replace or update on duplicate - did insert?

I am using php to 'insert ignore' a row into my database. Is there a way to find out whether a row was inserted?
the code looks like this:
if($stmt = $mysqli->prepare('INSERT IGNORE INTO my_table (key_a, key_b) VALUES (?, ?)'))
{
$stmt->bind_param('ss', 'hello', 'world');
$stmt->execute();
$stmt->close();
}
Thank you guys!
Try like this:
if($stmt->execute())
{
echo "Success";
}
else
{
echo "Error";
}
Also check mysqli::$affected_rows
$mysqli->affected_rows
mysqli::$affected_rows -- mysqli_affected_rows — Gets the number of
affected rows in a previous MySQL operation
Try the following: $mysqli->affected_rows
Link:
/* update rows */
$mysqli->query("UPDATE Language SET Status=1 WHERE Percentage > 50");
printf("Affected rows (UPDATE): %d\n", $mysqli->affected_rows);
MySQL has ON DUPLICATE KEY feature where you can define what to do if your insert fails because of some constrains like unique_key or primary_key being inserted twice.
On that cases, cases, you can trap such errors.
If the query inserts normally, it won't execute this block.
If the query fails, the block will be executed.
Now, you may tweak this feature.
For example, in your table, add one insert_attempts columns with default 0 (zero) value.
And try to execute:
INSERT INTO my_table (key_a, key_b)
VALUES (?, ?)
ON DUPLICATE KEY UPDATE
insert_attempts = insert_attempts+1
;
After all records are successful; SELECT the rows with insert_attempt > 0.
I think the execute() method will return a true or false, so I would suggest more sth. like this (also note that u need to do this before you close the connection):
if ($stmt->execute()) {
echo "success"
}
else
{
echo "Error"
}
, also consider to fetch the statement to see how many lines were affected. You can do that with mysqli_stmt_affected_rows(statement), it will give you the lines affected. If you use it, it couls look like this:
int mysqli_stmt_affected_rows ( mysqli_stmt $stmt )
also read here.

mysqli->insert_id on update (PHP)

Does it work for anyone? :P
I can properly get insert_id while inserting, but not on update. Of course contactsId column is AUTO_INCREMENT.
Whole code:
<?php
$mysqli = new mysqli('localhost', [USER], [PASSWORD], [DB]);
$mysqli->set_charset("utf8");
$query = 'INSERT INTO contacts (contactsName) VALUES ("Mariola")';
$result = $mysqli->query($query);
echo $mysqli->insert_id . '<br />';
$query = 'UPDATE contacts SET contactsName = "Mariola" WHERE contactsId = 289';
$result = $mysqli->query($query);
echo $mysqli->insert_id;
Output:
1514
0
I HAVE record with id 289, and update works fine.
This behavior is described very clear in the document.
mysqli::$insert_id -- mysqli_insert_id — Returns the auto generated
id used in the last query
If the last query wasn't an INSERT or UPDATE statement or if the
modified table does not have a column with the AUTO_INCREMENT
attribute, this function will return zero.
From MySQL documentation on LAST_INSERT_ID():
If expr is given as an argument to LAST_INSERT_ID(), the value of the argument is returned by the function and is remembered as the next value to be returned by LAST_INSERT_ID(). This can be used to simulate sequences:
Create a table to hold the sequence counter and initialize it:
mysql> CREATE TABLE sequence (id INT NOT NULL);
mysql> INSERT INTO sequence VALUES (0);
Use the table to generate sequence numbers like this:
mysql> UPDATE sequence SET id=LAST_INSERT_ID(id+1);
mysql> SELECT LAST_INSERT_ID();
The UPDATE statement increments the sequence counter and causes the next call to LAST_INSERT_ID() to return the updated value. The SELECT statement retrieves that value. The mysql_insert_id() C API function can also be used to get the value. See Section 20.6.7.37, “mysql_insert_id()”.
Maybe something like this will work:
$query = 'UPDATE contacts SET id = LAST_INSERT_ID(id), contactsName = "Mariola" WHERE contactsId = 289';

$mysql->info returns nothing

$db = new mysqli('localhost','x','x','rock');
$q = $db->query("INSERT INTO names (name,surname) VALUES ('jack','daniel')");
var_dump($q); // boolean true
echo $db->info;
doing everything as described in manual but still returns nothing.
If the insert statement is one of the below info function will return result
INSERT INTO...SELECT...
INSERT INTO...VALUES (...),(...),(...)
And your insert is not satisfying this condition.
you have
INSERT INTO names (name,surname) VALUES ('jack','daniel')
if you change this to insert more than one record you will see the result from info function
if you change your insert query to insert multiple record in once you will get result
Try with below
INSERT INTO names (name,surname) VALUES ('jack','daniel'),('jack2','daniel2')

Categories