Check Whether Particular query from multiple query is affected or not - php

Let Suppose i have Following code which updates two different table
if(isset($_POST['submit'])){
$updateq = $conn->query("UPDATE `tbl1` SET `field1`= '$field1'");
$updater = $conn->query("UPDATE `tbl2` SET field2 ='$field2'");
//Here I want to check if first update query
//is affected any row or not
if(mysqli_affected_rows($conn) > 0){
....
}
}
So is it possible to check whether first query is updated any row or not ?

IN mysql
ROW_COUNT() returns the number of rows changed, deleted, or inserted by the last statement if it was an UPDATE, DELETE, or
INSERT. For other statements, the value may not be meaningful.
so,
UPDATE `tbl1` SET `field1`= '$field1'
SET #countRow = ROW_COUNT();
if (#countRow>0) then
UPDATE `tbl2` SET field2 ='$field2'
end if;
you have to integrate this in php as it is purely mysql syntax

Related

Inserting data into multiple tables not functioning correctly

I have the following two tables
Table player:
player_id (int)(primary)
player_name (varchar)
player_report_count (int)
Table report:
report_id (int)(primary)
player_id
report_description
report_location
Firstly I ask the user for the player_name and insert it into the player database. From here the player is given an id.
Then I tried to grab the value of the players report count and increment the current value by one (which isn't working).
This is followed by grabbing the playerId from the player table and then inserting into the corresponding column from the report table (also does not work).
When I insert some values into the database, the names, description and report are added to the database however the playerID remains at 0 for all entries and the player_report_count remains at a consistent 0.
What is the correct way to make these two features function? And also is there a more efficient way of doing this?
<?php
$records = array();
if(!empty($_POST)){
if(isset($_POST['player_name'],
$_POST['report_description'],
$_POST['report_location'])){
$player_name = trim($_POST['player_name']);
$report_description = trim($_POST['report_description']);
$report_location = trim($_POST['report_location']);
if(!empty($player_name) && !empty($report_description) && !empty($report_location)){
$insertPlayer = $db->prepare("
INSERT INTO player (player_name)
VALUES (?)
");
$insertPlayer->bind_param('s', $player_name);
$reportCount = $db->query("
UPDATE player
SET player_report_count = player_report_count + 1
WHERE
player_name = $player_name
");
$getPlayerId = $db->query("
SELECT player_id
FROM player
WHERE player_name = $player_name
");
$insertReport = $db->prepare("
INSERT INTO report (player_id, report_description, report_location)
VALUES (?, ?, ?)
");
$insertReport->bind_param('iss', $getPlayerId, $report_description, $report_location);
if($insertPlayer->execute()
&& $insertReport->execute()
){
header('Location: insert.php');
die();
}
}
}
Main issue here is you are getting player details before inserting it. $getPlayerId will return empty result always.
Please follow the order as follows.
Insert player details in to player table and get payerid with mysql_insert_id. After binding you need to execute to insert details to the table.
Then bind and execute insert report .
Then update the player table by incrementing report count with playerid which you got in step 1.
Note : use transactions when inserting multiple table. This will help you to rollback if any insert fails.
MySQL Query will return result object. Refer it from here https://stackoverflow.com/a/13791544/3045153
I hope it will help you
If you need to catch the ID of the last insterted player, This is the function you need if you're using PDO or if it's a custom Mysql Class, you need the return value of mysql_insert_id() (or mysqli_insert_id()) and then directly use it in the next INSERT INTO statement

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'

How to determine if MySQL UPDATE actually matched any rows with WHERE clause?

I want to run an update like such in PHP
// pseudocode
UPDATE invoice SET due_date=? WHERE invoice_id=? AND creater_id=?;
IF AFFECTED_ROWS == 1 THEN
UPDATE invoice_item SET price=? WHERE invoice_id=?
For added security, I appended creater_id to ensure that the code only updates if the logged in user is the invoice creator, otherwise, the system will not update.
I originally intended to check this condition using AFFECTED_ROWS. But eventually after much frustration, I realise AFFECTED_ROWS return 0 if all the new values are the same as the old values. This means that even if I have different values for the invoice_item, they will not be updated.
Other than doing a SELECT before the UPDATE, is there SQL query or PHP functions that will tell me if the UPDATE matched any row, so that I can proceeed to UPDATE invoice_item accordingly?
You can use ROW_COUNT() and if you read that it explains that when connecting to the DB you can specify the CLIENT_FOUND_ROWS flag which will give the number of rows found for the update, regardless of if they have the same value of what you're updating with.
Hope this helps.
I've taken this from my code so things like $link need to be in place- but it shows what you are interested in
function update() {
$q = "UPDATE table SET field1=? WHERE field2 = $value";
/* create a prepared statement */
$stmt = mysqli_stmt_init($link);
if (mysqli_stmt_prepare($stmt, $q)) {
mysqli_stmt_bind_param($stmt, "s", $field1);
mysqli_stmt_execute($stmt);
if(mysqli_stmt_errno($stmt)){
echo("Sql Error: ".$q. ' Sql error #: '.mysqli_stmt_errno($stmt). ' - ' . mysqli_stmt_error($stmt);
return false;
}
else{
$numrows = mysqli_stmt_affected_rows($stmt);
if (mysqli_stmt_errno($stmt) == 0 || mysqli_stmt_errno($stmt) ==''){
// numrows = -1 is flag no error and no rows affected
$numrows = ($numrows ==0?-1:$numrows);
}
else{
echo("Sql Error: ".$q. ' Sql error #: '.mysqli_stmt_errno($stmt). ' - ' . mysqli_stmt_error($stmt);
return false;
}
/* close statement */
mysqli_stmt_close($stmt);
return $numrows;
}
}
}
As per documentation on ROW_COUNT():
ROW_COUNT() returns the number of rows changed, deleted, or inserted by the last statement if it was an UPDATE, DELETE, or INSERT. For other statements, the value may not be meaningful.
Your query:
Other than doing a SELECT before the UPDATE, is there SQL query or PHP functions that will tell me if the UPDATE matched any row
You can also use ROW_COUNT() within an UPDATE or any other DDL or DML statement.
Example: Using your pseudocode:
// pseudocode
UPDATE invoice SET due_date=? WHERE invoice_id=? AND creater_id=?;
IF ( ROW_COUNT() >= 1 ) THEN
UPDATE invoice_item SET price=? WHERE invoice_id=?
END IF;
Or else, you can try like:
UPDATE invoice SET due_date=? WHERE invoice_id=? AND creater_id=?;
UPDATE invoice_item SET price=
(case when ( row_count() >= 1 ) then ? else price end)
WHERE invoice_id=?;
Before setting the parameter value check again for the row_count() value to decide whether to set values for 1 or more parameters.
You can take this back to 1 query and not worry about affected rows:
UPDATE
invoice
left join invoice_item on invoice_item.invoice_id = invoice.invoice_id
SET
invoice.due_date = ?, -- the WHERE will only let this happen if it will be changed
invoice_item.price = ? -- the WHERE will only let this happen if it will be changed
WHERE
invoice.invoice_id = ?
and invoice.creater_id = ?
and invoice.due_date != ? -- here compare the new due_date to the one already in the db

How to determine success of MySQL transaction

In a regular single query statement to MySQL, I can use mysql_affected_rows()==1 to determine whether or not something was updated. Now suppose I am trying to perform a transaction of the following:
USE myDB;
START TRANSACTION;
UPDATE members SET member_active=0 WHERE member_id = 53;
UPDATE member_subscriptions SET subscription_active=0 WHERE member_id = 53;
COMMIT;
ROLLBACK;
Since I have those two update statements, should I could on a successful transaction being equivalent to mysql_affected_rows()==2 ?
OR, is there a better way I should be checking for success?
You should hold the value of mysql_affected_rows in variables. And total updation will be some of those variables.
If you have track of both transactions and can have even better judgment which transaction is not performed and what would be the reaction.
USE myDB;
START TRANSACTION;
UPDATE members SET member_active=0 WHERE member_id = 53;
$count1= mysql_affected_rows();
UPDATE member_subscriptions SET subscription_active=0 WHERE member_id = 53;
$count2= mysql_affected_rows();
COMMIT;
ROLLBACK;
$total_affected_rows = $count1 + $count2;
Yes checking mysql_affected_rows()==2 is an alternative way from application level.
Its going to be 100% successful(commit) or nothing (rolled back) as you are using proper transactions.
EDIT: You can use ROW_COUNT() function in MySQL to get affected rows from last query as:
USE myDB;
START TRANSACTION;
UPDATE members SET member_active=0 WHERE member_id = 53;
SELECT ROW_COUNT() INTO #count1;
UPDATE member_subscriptions SET subscription_active=0 WHERE member_id = 53;
SELECT ROW_COUNT() INTO #count2;
COMMIT;
ROLLBACK;
then the sum of these should be equals to 2
SELECT ((#count1 + #count2) = 2) AS status;

Update int in MySQL Field

How can I increment an int in a cell of a MySQL database? I know that auto-increment is no use because I never want to add a new row, just update an existing one. I'm currently using this (POST var used for clarify, is verified in the real code):
$columnToUpdate = 'type'.$_POST['voteid'];
$query = "UPDATE myTable $columnToUpdate = $columnToUpdate+1 WHERE id=1;";
if(!mysql_query($query)) {
echo json_encode(array('success' => false, 'message' => 'Update failed: '.mysql_error()));
exit;
}
In the database I have 6 fields, id, type1, type2, type3, type4, type5, and a single row with id set to 1. The intention is to recieve a number (1-5), and build a reference to the correct column before updating the field. That results in Update failed: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '=type4+1 WHERE id=1' at line 1, so I guess it's not getting the field value out properly before it increments.
Once this is working I'm also going to need to decrement a field in the same way, unless its value is 0. So for bonus points, can I do all this in one query or would it be better to split it up?
I think you've missed the keyword 'SET' from your query - try
$query = "UPDATE myTable SET $columnToUpdate = $columnToUpdate+1 WHERE id=1;";
Edit:
To do the "decrement unless it's zero" you could use something like:
UPDATE myTable SET $columnToUpdate =
CASE $columnToUpdate
WHEN 0 THEN 0
ELSE $columnToUpdate - 1
END CASE
WHERE id=1;`
For bonus points, to decrement:
$query = "UPDATE myTable SET '$columnToUpdate' = '$columnToUpdate'-1 WHERE id=1 AND '$columnToUpdate' > 0";
Besides the injection issues, it seems as if your workflow may need some work. Are you sure you want to choose the column that will be updated based on POST variable? It seems like you would specify the column and use the variable to find the record that needs to be updated:
IE:
"UPDATE myTable SET votes=votes+1 WHERE id=$post_variable;"
Again you should send the variable as a parameterized query to protect yourself from SQL injection.

Categories