Update MYSQL row with non null value only - php

i have a table contain huge number of rows and i need to update row with specific ID, for example assume i have a row with below details:
Id= 1
Name= lessa
Address = USA
now i used below PHP code to update the row:
<?php
$con = mysqli_connect("localhost","MyUserName","MyPassword","DB");
$id = '1';
$name = "";
$address = "UK";
// update only non value items
$r=mysqli_query($sql);
mysqli_close($con);
?>
now my issue since the value of address is changed from USA to UK i need to update this value only, also since the name value is nothing the name should be remain so after update the row should be like below:
ID=1
Name = lessa
Address = UK
Also if in another time the name value changed and address remain the same i need to update the name only.
also assume i have 100 column not only three as this example.
any help for write the update statement will be appreciated.
Update:
I use below code but no update happen:
<?php
$con = mysqli_connect(DB info);
$id = 'jo_12';
$name = "";
$address = "UK";
$sql = "UPDATE info
SET name = IF(? = '', name, ?),
address = IF(? = '', address, ?)
WHERE id = ?";
$stmt = $con->prepare($sql);
$stmt->bind_param("ssssi", $name, $name, $address, $address, $id);
$stmt->execute();
mysqli_close($con);
?>

Put tests in the UPDATE query:
$sql = "UPDATE yourTable
SET name = IF(? = '', name, ?),
address = IF(? = '', address, ?)
WHERE id = ?";
$stmt = $con->prepare($sql) or die ($con->error);
$stmt->bind_param("sssss", $name, $name, $address, $address, $id);
$stmt->execute();
The IF() tests assign the old value of the column back to it if the variable is empty.

Try to use this SQL query:
UPDATE table_name SET Address='UK' WHERE ID=1
You can of course substitute ID=1 for any other number.

Related

getting single cell from database using PDO

I am trying to get a piece of data from my database but would like to only get one cell using the PDO statement if this is possible.
Below is a screenshot of the table
The table name is called heating
I am trying to get the data from column called 'garage' and row id = 3
I have tried many ways but keep failing. The following is what I have so far but only returns the column name garage for some reason.
I am using the following which gives me the name garage
$room = 'garage';
require_once "connect.php";
$sql = 'SELECT :name FROM heating WHERE id = 3';
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':name', $room);
$stmt->execute();
$sw = $stmt->fetch();
echo $sw[0];
If I do the following I gives me the correct outcome but I would like to replace garage with a variable
$sql = 'SELECT garage FROM heating WHERE id = 3';
$stmt = $pdo->prepare($sql);
$stmt->execute();
$sw = $stmt->fetch();
echo $sw[0];
You can create a white list of your column names and use it to select the right column. You can check the column against a white list with the help of in_array. The third parameter is very important as it checks that string is a string. You can only then safely concatenate the SQL with your PHP variables using PHP concatenation operator. For the good measure, the column names should be enclosed in backticks `, in case any of your column names is a reserved word or contains special characters.
$whiteListOfHeating = [
'keyName',
'den',
'WC1',
'hallway',
'garage'
];
$room = 'garage';
if (in_array($room, $whiteListOfHeating, true)) {
$sql = 'SELECT `'.$room.'` FROM heating WHERE id = 3';
$stmt = $pdo->prepare($sql);
// ...
} else {
echo 'Invalid column name specified!';
}
Sometimes simplest solutions are best.
require_once "connect.php";
$room = 'garage';
$sql = 'SELECT * FROM heating WHERE id = ?';
$stmt = $pdo->prepare($sql);
$stmt->execute([3]);
$sw = $stmt->fetch();
echo $sw[$room];
Besides, every time you need such a functionality, in means that most likely your database structure is wrong. A room should be a row, not column
require_once "connect.php";
$room = 'garage';
$sql = 'SELECT value FROM heating_room WHERE heating_id=3 and room = ?';
$stmt = $pdo->prepare($sql);
$stmt->execute([$room]);
$sw = $stmt->fetchColumn();
echo $sw;
will make it straight

PHP Update query is being executed, but the credentials are not updated

I have a form tag on my site that leads to the PHP page with email and/or/without description. Based on that the code generates a query, the query needs to update these credidentials. That part of the code works and has been tested. The problem is that the database is not updating the e-mail credidential, but if i put it to update the description it does so. The code has 3 checks, if the user puts only his email, if he puts only his description or puts both. Based on that the code works like this :
<?php
session_start();
include_once 'connection.php';
$id = $_SESSION['user_id'];
if(isset($_POST['emailChange']) || isset($_POST['descChange'])){
$desc = $_POST['descChange'];
$email = $_POST['emailChange'];
if(empty($email)){
$query = "UPDATE users SET description = :descr WHERE user_id= :id ;";
$stmt = $conn->prepare($query);
$stmt->bindParam(":descr", $desc);
} else if(empty($desc)){
$query = "UPDATE users SET user_email= :email WHERE user_id= :id ;";
$stmt = $conn->prepare($query);
$stmt->bindParam(":email", $email);
} else{
$query = "UPDATE users SET description = :descr AND user_email = :email WHERE user_id= :id;";
$stmt = $conn->prepare($query);
$stmt->bindParam(":email", $email);
$stmt->bindParam(":descr", $desc);
}
if(!filter_var($email, FILTER_VALIDATE_EMAIL)){
header("Location: ../profile.php?error=invalidEmail");
exit();
}
$stmt->bindParam(":id", $id);
$stmt->execute();
}
The form itself looks like this :
<form action="assets/upload.php" method="POST">
<input type="text" name="emailChange" class="inputs" id="changeEmail" placeholder = "Enter your new E-mail">
<input type="text" name="descChange" class="inputs" id="changeDesc" placeholder="Enter your description">
<button type="submit" id="btnconfirmCreds" name="changeCreds">Confirm Changes</button>
</form>
The names in the database looks like this :
[user_id][user_username][user_email][user_password][role_id][user_image][description][num_of_posts]
You should set up PDO error logging.
From Comments; paraphrased for clarity:
My user_id column is int(11) auto_increment
Your problem is you are trying to insert a string value into a numerical column in MySQL.
user_id / id in database parlance is usually a numerical value, but you have not set the value type in your SQL, so it defaults to string.
Because your :id value is a numeric value in PHP you need to do this:
$stmt->bindParam(":id", $id, 'i'); // i = integer type.
It is highly recommended to explicitly set the value of the data type supplied each and every time .
If the data given to the PDO does not match the value-type given, then the PDO transaction will void and will not complete. This is a security measure.
For example:
$id = 3;
$stmt->bindParam(":id", $id);
This is the same as saying:
$stmt->bindParam(":id", 3, 's'); // default type value is 's' for string.
Obviously the value 3 is not a string so this transacion ($stmt) is never performed.
i assume it's because it views the description as a special word, if that is true then i should change the name in my database. Thoughts?
"description" is neither a Keyword or a reserved word in MySQL 5.5-->5.7 (in MySQL 8.0.4 DESCRIPTION is a keyword but is not a reserved word)
You can view a list of MySQL Keywords and Reserved words .
Some notes about the logic:
if(isset($_POST['emailChange']) || isset($_POST['descChange']))
{
$desc = $_POST['descChange'];
$email = $_POST['emailChange'];
...
First you check, if at lease one parameter exists, but then you access both. You can argue, that the form send always both, but never believe user input: Manipulating data is so easy!
Either change your if(...) to:
if( isset($_POST['emailChange']) && isset($_POST['descChange']) )
The following line is a shorter form with identical semantics:
if( isset( $_POST['emailChange'], $_POST['descChange'] ) )
The other ways is to change the 2 other lines, for example by:
$desc = isset($_POST['descChange']) ? $_POST['descChange'] : '';
$email = isset($_POST['emailChange']) ? $_POST['emailChange'] : '';

Update the row if value matches else Insert a new row

I'm creating a table for student to insert for Entrance Exam for with following value(id (primary key), name, symbol, address)
and later they will print admit card.
If they double enter their value and if there already exist an row for same value of symbol, I would like to update name and address to new value if there instead of inserting new one.
How can I do that..?
My Mysql Database is
$name = $_POST['name'];
$symbol = $_POST['symbol'];
$address = $_POST['address'];
$sql = "
IF NOT EXISTS (SELECT * FROM entrance WHERE symbol = :symbol)
INSERT INTO entrance(
name,
symbol,
address) VALUES(:name,:symbol,:address)
ELSE
UPDATE entrance SET name = :name, address = :address WHERE symbol =
:symbol
";
$q = $db->prepare($sql);
$q->execute(array(':name'=>$a,':symbol'=>$symbol,':address'=>$address,))
You could work with IF NOT EXISTS in your SQL.
IF NOT EXISTS (SELECT * FROM entrance WHERE symbol = :symbol)
INSERT INTO entrance(
name,
symbol,
address) VALUES(:name,:symbol,:address)
ELSE
UPDATE entrance SET name = :name, address = :address WHERE symbol = :symbol
First check if the data is in database by using select query
$select = "SELECT * FROM entrance WHERE symbol='$symbol'";
If select query return rows>0 then run update query else insert Query

PHP PDO search for a value in two or more columns using one string

When I want to find a value from a row using PDO I use the following method:
//Search whether user exists
$sqlQueryEmailLogin = $dbh->prepare("SELECT vendor_id, first_name, last_name, email_login, user_password, passport_id, login_attempts, login_last_attempt FROM $tableVendorDetails WHERE email_login = ?");
$sqlQueryEmailLogin->bindValue(1, $emailLogin);
$sqlQueryEmailLogin->execute();
and the following PHP code for the search field
$emailLogin = 'xyz#abc.com'
Now I'd like to search two columns or more and use the following code
$sql = "SELECT * FROM articles WHERE id = ? AND status = ?";
$stmt = $conn->prepare($sql);
$stmt->bindValue(1, $id);
$stmt->bindValue(2, $status);
$stmt->execute();
I'd like to search the two columns from a string. How should I go about it, please?
The string value i go is from a html form with one input box
I'd like a string that is capable of searching two values from a MySQL table e.g.
$search = $id; and
$seach = $status;
in this case both cancel each other
You could simplify it by using the method described by #gbestard. But you should also do this:
$search = 'asdf'; // fill this with your form input
$sql = "SELECT * FROM articles WHERE id = :id OR status = :status";
$stmt = $conn->prepare($sql);
$stmt->execute(array(
':id' => $search,
':status' => $search,
));
Notice the change to OR in the query, and supplying the $search multiple times...
That's what I'm using
$sql = "SELECT * FROM articles WHERE id = :id AND status = :status";
$stmt = $conn->prepare($sql);
$stmt->execute(array(':id' => $id , ':status' => $status));
Try the following
$sql = "SELECT * FROM articles WHERE id = :id AND status = :status";
$stmt = $conn->prepare($sql);
$stmt->bindValue(':id', $id);
$stmt->bindValue(':status', $status);
$stmt->execute();
See docs http://php.net/manual/en/pdostatement.bindvalue.php
You should use OR instead of AND. That way, you will get all rows that match either by id or by status.
SELECT * FROM articles WHERE id = ? OR status = ?

Why does this UPDATE procedure update every row?

I have a MySQL stored procedure like this
UPDATE `Discounts` SET `Occupation`=occupation,
`Organization`=organization,
`LastName`=lastName,
`FirstName`=firstName,
`Email`=email,
`Phone`=phone,
`Description`=description,
`ExpirationDate`=expiration,
`Notes`=notes
WHERE `ID` = id
and I'm calling it with this PHP
$occupation = $_POST["occupation"];
$organization = $_POST["organization"];
$last = $_POST["last"];
$first = $_POST["first"];
$email = $_POST["email"];
$phone = $_POST["phone"];
$description = $_POST["description"];
$notes = $_POST["notes"];
$expiration = date("Y-m-d H:i:s", strtotime($_POST["expiration"]));
$id = intval($_POST["id"], 10);
$password = $_POST["password"];
$mysqli = new mysqli("localhost", "xxx", $password, "xxxxxxxx");
if ($mysqli->connect_errno) {
die("Could not connect");
}
$stmt = mysqli_stmt_init($mysqli);
if (mysqli_stmt_prepare($stmt, 'CALL UpdateDiscount(?,?,?,?,?,?,?,?,?,?)')) {
mysqli_stmt_bind_param($stmt, "isssssssss",
$id,
$occupation,
$last,
$first,
$email,
$phone,
$description,
$organization,
$notes,
$expiration);
mysqli_stmt_execute($stmt);
mysqli_stmt_close($stmt);
echo "Success!";
}
The update works exactly as I expected except that it updates every single row instead of the one row corresponding to the ID. I can't understand why this is happening, I have a WHERE 'ID'=id check. What is going on? How can I make it so that it only updates a single row?
Because `ID` is the case sensitive name of your column and id is the case insensitive name of the same column.
edit this is wrong: You should be using a PHP variable where the lowercase id is. Something like $id.
In your case you're calling a procedure with bound parameters.
Use a different name for the id parameter.
It's an issue of name-scoping local variable beloging to the procedure, versus argument variable belonging to the procedure versus the table column name.
In stored procedures, when a name conflict occurs between field and parameter names, the parameters are used.
Your query is parsed as:
UPDATE ...
WHERE :id = :id
which is always true (unless you pass a NULL)
Prepend the parameter names with an underscore:
CREATE PROCEDURE myprc (_id, _occupation, ...)
AS
BEGIN
UPDATE mytable
SET occupation = _occupation
WHERE id = _id;
END;

Categories