I'm updating a MySQL table with posted PHP data.
I first gather the posted data, and put them in appropriate variables. Together with the necessary if/else checks.
Then, I only have to write my query once.
But now I have an if/else to check wether to update a specific field or not. How can I store a "do-not-update" value inside the corresponding variable?
Because otherwise I have to put an if/else check around the whole query, just for one field.
I just want to be as efficient as possible. :)
My query is as follows:
$updateTable = mysql_query("UPDATE myTable SET field1 = '$field1', field2 = '$field2'");
wherever you are get $_POST into variables, do this,
if( $field2 === 'xyz' ) { //if value is 'xyz', do not update
$sql = '';
} else
$sql = ", field2 = '$field2'";
Then in the query,
$updateTable = mysql_query("UPDATE myTable SET field1 = '$field1' $sql");
Edit: if using 1/0 (true or false),
if( $field2 == true ) { //if value is true, do not update
$sql = '';
} else
$sql = ", field2 = '$field2'";
You will need to build up your query, storing it in a PHP string, for example:
$sql = "UPDATE `table` SET ";
if ($_POST['foo']!=='') {
$sql .= " `foo`='".mysql_real_escape_string($_POST['foo'])."',";
}
if ($_POST['bar']!=='') {
$sql .= " `bar`='".mysql_real_escape_string($_POST['bar'])."',";
}
$sql = rtrim($sql,',');
$sql .= " WHERE `id`='".mysql_real_escape_string($_POST['id'])."'"
Then execute your string as the query.
If you are asking whether the field should be updated, you can do one of two things:
1) Specify a criteria that ensures field1 and field2 are only updated if the rows match the criteria. If the criteria does not match, the record will not be updated. This is the most common way.
UPDATE myTable ...
WHERE criteria1 = 1 AND criteria2 = 'Red'
2) Run a query before the UPDATE to see whether to perform an update.
I'm not exactly sure what you are asking for, but perhaps this answers your question:
$updateTable = mysql_query("
UPDATE myTable SET
field1 = IF('$field1'>'','$field1', field1),
field2 = IF('$field2'>'','$field2', field2)
");
Of course, you are opening yourself up to SQL injection with the code, as written.
Lets assume you have gathered the fields to update in an array $fields like this :
array (
'filed1' => 'value' ,
'field2' => ''value
)
Now you need to generate the query, you can do this by looping in the array:
$sql = "UPDATE mytable ";
$sql .= $fields ? "SET " : "" ;
foreach ($fields as $key=>$value) {
$sql.= $value ? "$key = '$value' , " : '' ;
}
//you need to omit the trailing ','
$sql[strlen($sql) -1 ] = "";
Tips :
Do sanitize all user input using mysqli_real_escape_string or something better than that.
Happy coding :)
Related
I tried
$sql = "update ad_group_keyword set status = :status where google_id not in (:google_id)";
Yii::$app->db->createCommand($sql)
->bindValue(':status', Constants::DELETED)
->bindValue(':google_id', join(',',$googleIds), \PDO::PARAM_INT)
->execute();
but it turned the array of ids into one giant string, despite the PDO::PARAM_INT. I also tried
->bindValue(':google_id', $googleIds)
but it gave an 'Array to string conversion' in vendor/yiisoft/yii2/db/Command.php:172. I ended up using
$sql = "update ad_group_keyword set status = :status where google_id not in (" . join(',',$googleIds) . ")";
I suggest use QueryBuilder for this function:
$command = Yii::$app->db->createCommand();
$result = $command->update( // create a update sql
'ad_group_keyword', // table
['status'=>1], // update set
['NOT IN', 'google_id', [1,2,3]] // where
)->execute();
You can read the \yii\db\Command::update() DOC, and how to set condition
You shouldn't have a join in there at that place. That is where it is being turned into a string. You want to iterate through your list of ids and bindValue each one to the variable in turn.
You'll need to bind each of the array values individually. Something like this:
$sql = "UPDATE ad_group_keyword
SET status = :status
WHERE google_id NOT IN(%s)";
$bindValues = array();
$i = 0;
foreach ($googleIds as $value)
{
$bindValues[':googleId'.$i++] = $value;
}
$sql = sprintf($sql, join(', ', array_keys($bindValues)));
$sqlCommand = Yii::$app->db->createCommand($sql);
$sqlCommand->bindValue(':status', Constants::DELETED);
foreach ($bindValues as $key => $value)
{
$sqlCommand->bindValue($key, $value, \PDO::PARAM_INT);
}
$sqlCommand->execute();
However, I'm only basing this example on your code and I'd look into Yii's manual to see if there already isn't a method that does all of this work for you ... it shouldn't be that hard to safely execute an SQL query using IN().
I'm trying to write a query to check which column to update. The user sends an action which they performed (a like or a comment) and I'm trying to update a table. Is it possible to check inside the query which column to update? For example:
DB structure:
id imageName imageLikesCount imageCommentsCount
$actionPerformed = "like";
mysqli_query($link, "UPDATE table (if $actionPerformed=like SET imageLikesCount+1
else imageCommentsCount+1)
WHERE imageName='$image'");
I'm not sure how to phrase that, if it's possible at all. Any advice? Thanks in advance!
though meverhart913 has a way to do it, the better way to do the same thing is to instantiate your variable based on the if condition, then just plug that variable into your string. This keeps you from having to repeat your string over and over as well as allows you to easily add additional conditions.
if($actionPerformed=="like"){
$col = imageLikesCount;
else{
$col = imageCommentsCount;
}
mysqli_query($link, "Update table SET '$col' = '$col + 1' where imageName = '$image'");
if($actionPerformed=="like"){
mysqli_query($link, "Update table SET imageLikesCount = imageLikesCount + 1 where imageName = '$image'");
}
else {
mysqli_query($link, "Update table SET imageCommentsCount = imageCommentsCount + 1 where imageName = '$image'");
}
I'm not a php programmer so my syntax won't be correct, but here are two ways to do it:
if ($actionPerformed == "like")
query for updating imageLikesCount
else if ($actionPerformed == "comment")
query for updating imageCommentsCount
else
whatever
Or
if ($actionPerformed == "like")
$column = "imageLikesCount";
else ($actionPerformed == "comment")
$column = "imageCommentsCount";
$sql = "update table set $column = $column + 1";
Then execute it.
Ok..I know how to get a data record from a MySql table...and I want to change data in that record and update the table.
My question is...can you actually manipulate that data from the result row, and subsequently use those in the update statement?
For example.
Let's say the table rows have 2 fields: Name, YearlyEarn.
And once a month I want to add that month's income to the YearlyEarn field for each person.
Assume we already did the Select statement for someone who's name is in $CurrentName.
And we then get their record.
$DataRow = mysql_fetch_array($result):
Can you do this:
$DataRow["YearlyEarn"] = $DataRow["YearlyEarn"] + $MonthEarn;
$query = "UPDATE EarnTable SET YearlyEarn = '$DataRow["YearlyEarn"]'
`WHERE Name = '$CurrentName'" ;
$UpdResult = mysql_query($query) or die(mysql_error());
OR.....should I put the data into intermediate fields, manipulate it..and then use those fields in the update statement?
You should use prepared statements, like PDO. The mysql_* is outdated. But if not doing so, you should consider changing your query from:
$query = "UPDATE EarnTable SET YearlyEarn = '$DataRow["YearlyEarn"]'`WHERE Name = '$CurrentName'" ;
to:
$query = "UPDATE EarnTable SET YearlyEarn = `" . $DataRow['YearlyEarn'] . "` WHERE Name = `$CurrentName`" ;
Yes, you can:
UPDATE EarnTable
SET YearlyEarn = YearlyEarn + 123
WHERE Name = 'abc'
You can use:
$query = "UPDATE EarnTable SET YearlyEarn = '$DataRow[YearlyEarn]' WHERE Name = '$CurrentName'" ;
When you're interpolating an array reference, the key is automatically quoted.
or:
$query = "UPDATE EarnTable SET YearlyEarn = '{$DataRow["YearlyEarn"]}' WHERE Name = '$CurrentName'" ;
Inside {...}, you can put any variable expression and it will be evaluated and interpolated.
How would I not include text fields of a form left blank in a MySQL update query? I understand why it's replacing filled fields with empty strings, but I'm not sure of an efficient way to fix it. Is the best option really just a lot of if statements? Is there some kind of function I could use to disallow blank fields in my html form?
Here's what I have so far:
//Check if record exists
if(mysql_num_rows(mysql_query("SELECT Item_Id FROM Item_t WHERE Item_Id = '$itemid'")) == 0){
die('The Item ID you entered was not found. Please go back and try again.');
}
//Update record
$update = "UPDATE Item_t SET Item_Name='$itemname', Item_Price='$itemprice' WHERE Item_Id='$itemid'";
mysql_query($update);
So basically, in this example, if you leave the field that sets $itemname blank and just update $itemprice, the price will be updated, but the name will be set to an empty string.
You can check if your strings are empty in the SQL:
UPDATE Item_t
SET Item_Name = IF('$itemname' = '', Item_Name, '$itemname'),
Item_Price = IF('$itemprice' = '', Item_Price, 'itemprice')
WHERE Item_Id='$itemid'
If you're building the update string in php, you might as well just build it differently if it's empty:
$update = "UPDATE Item_t SET ".($itemname ? "Item_Name='$itemname', " : "")."Item_Price='$itemprice' WHERE Item_Id='$itemid'";
try something like this.
$strSet = '';
//make sure to sanitize your inputs first, then do this....
if(Item_Name != ''){ $strSet .= 'Item_Name=\'$itemname\','};
if(Item_Price != ''){ $strSet .= 'Item_Price=\'$itemprice\','};
//removes trailing comma
$strSet = substr($strSet,0,-1);
//Update record
$update = "UPDATE Item_t SET " . $strSet . " WHERE Item_Id='$itemid'";
mysql_query($update);
I'm very new to php/SQL (1 day) so forgive me if I am doing this in a backwards way.
This php below is intended to return the 100 most recent entries into the DB. I attempt to do it by selecting 100 entries to be returned and sort by the date(time stamp) the entry was made. Will this return the 100 more recent entries to the DB? Or am I understanding this wrong?
$type = isset($_GET['type']) ? $_GET['type'] : "global";
$offset = isset($_GET['offset']) ? $_GET['offset'] : "0";
$count = isset($_GET['count']) ? $_GET['count'] : "100";
$sort = isset($_GET['sort']) ? $_GET['sort'] : "date DESC";
// Localize the GET variables
$udid = isset($_GET['udid']) ? $_GET['udid'] : "";
$name = isset($_GET['name']) ? $_GET['name'] : "";
// Protect against sql injections
$type = mysql_real_escape_string($type);
$offset = mysql_real_escape_string($offset);
$count = mysql_real_escape_string($count);
$sort = mysql_real_escape_string($sort);
$udid = mysql_real_escape_string($udid);
$name = mysql_real_escape_string($name);
// Build the sql query
$sql = "SELECT * FROM $table WHERE ";
switch($type) {
case "global":
$sql .= "1 ";
break;
case "device":
$sql .= "udid = '$udid' ";
break;
case "name":
$sql .= "name = '$name' ";
break;
}
$sql .= "ORDER BY $sort ";
$sql .= "LIMIT $offset,$count ";
$result = mysql_query($sql,$conn);
if(!$result) {
die("Error retrieving scores " . mysql_error());
}
//echo $result;
$rows = array();
while($row = mysql_fetch_assoc($result)) {
$rows[] = $row;
}
This should work, although date is a MySQL keyword, so you would either need to enclose date in backquotes or rename that column.
Also, definitely make sure you've sanitized those inputs before building your query. Building a query off of user-editable values from $_GET or $_POST with no sanitation is very unsafe.
For WHERE parameters, you should be running mysql_real_escape_string() on those (which I see you are, I'm not sure if you were before or not). That's enough because you're wrapping those values in quotes in your query, and since you're escaping that string, any attempt to break out of those quotes won't work.
For the stuff like the ORDER BY you have, I would define a valid "list" of allowed values and check to make sure your parameter is in that list. For example:
$valid_orderbys = array('`date` DESC', '`date` ASC', '`name` DESC', '`name` ASC');
if (in_array($_GET['sort'], $valid_orderbys))
{
// you're good, you can use this value
}
else
{
// unexpected value, either alert the user or
// use a default value you define
}
Or for LIMIT, you could use PHP's built-in is_numeric() to verify that the value you're being given is a number, not a crafted string.
It's not enough to simply escape the $table, ORDER BY and LIMIT parameters because they're not wrapped in quotes and therefore someone can just maliciously inject a value of ; DROP TABLE whatever; --. This ends up making your query something like:
SELECT * FROM ; DROP TABLE whatever; --WHERE ...
Queries are separated by semicolons, so there are three queries here. The first fails because it's invalid, the second succeeds in dropping the table, and the third is just a comment so nothing happens. But you can see, if you let users throw whatever they want as one of those parameters, it's a wide open security hole. (I'm not sure if enclosing the table name in backquotes helps this, someone let me know if you know. But in any case, you can do the same attack on the LIMIT and ORDER BY parameters.)
If you have a unique, auto-increment ID for each record (as you should), it would be more efficient to ORDER BY id DESC.
Actually, you already got it right. You should only look into specifying the columns instead of using *.