I'm having an issue that I can't quite figure out. I have a bit of code that allows a user to pick, let's say, which type of fruit is their favourite. If they've previously selected 'apples' as their favourite and want to change it to 'oranges' - the script performs well.
But if they select 'apples' when they've already selected 'apples' the MYSQL Update call breaks down and returns an error. It's like it won't write over itself with the same data, that the new value has to be unique. I'm at a loss.... Here's the update bit:
// UPDATE THEIR FRUIT SELECTION...
$q = "UPDATE account SET fav_fruit='" . $row['fruit'] . "' WHERE act_id=$act_id LIMIT 1";
$r = #mysqli_query ($dbc, $q);
if (mysqli_affected_rows($dbc) == 1) { // If it ran OK.
echo 'success!';
} else {
echo 'oops!';
}
Again, this works so long as the new selection and what's in the database aren't the same. If they are: I get the oops! error.
Why would you need to update a field to contain a value it already contains?
Regardless, this can be fixed by altering the table structure. You need to remove the unique flag from the fav_fruit column.
Related
So, I've been looking for a solution to my case, but I've kept finding only partial and not quite solving-the-matter kind of answers.
First, let me describe what I'm trying to achieve.
In my database I have two tables: PLACES and PLACES_CATEGORIES which are connected by a third table PLACES_A_CATEGORIES in an entity many to many. That is because a PLACE can be characterised by one or more CATEGORIES (but it can also have no CATEGORIES at all).
I want to add data send in one form to two tables: PLACES and PLACES_A_CATEGORIES. The user has all the categories listed with checkboxes and he may (but doesnt have to) check one or more of them.
I automated the display of those checkboxes so it reacts accordingly to changes in database (like adding or removing categories). This part works just fine, but let me show the code for you as it may be useful in solving the real issue:
$query = "SELECT name FROM places_categories";
$result = $connection->query($query);
$category_no = $result->num_rows;
echo "Categories of places:";
for ($j = 0; $j < $category_no; ++$j)
{
$category = $result->fetch_assoc()['name'];
echo '<br><input type="checkbox" id="'.$category.'" name="places_categories" value="'.$category.'"><label for="'.$category.'">'.$category.'</label><br>';
}
So, let's return to the problem. I want to:
always add data (only one row) to the table PLACES
add as many rows of data to the table PLACES_A_CATEGORIES as many checkboxes have been checked
So, let me now show you how I've tried to solve the matter and below I'll explain what and why I've done.
if ($everything_OK==true)//Hurra, everything is ok, lets add the place to the database
{
mysqli_query($connection, "SET NAMES utf8");//need it for special characters
//Adding multiple rows of data to database
$query = "SELECT name FROM places_categories";
$result = $connection->query($query);
$category_no = $result->num_rows;
for ($j = 0; $j < $category_no; ++$j)
{
$category[$j] = $result->fetch_assoc()['name'];
if ($_POST['places_categories'] == $category[$j])
{
//counts number of records in table PLACES
$query1 = "SELECT name FROM places";
$result1 = $connection->query($query1);
$places_no = $result1->num_rows;
$places_no += 1;
//looks for category_id in table places_categories where the name matches the current value from form
$query2 = "SELECT category_id FROM places_categories WHERE name='$category[$j]'";
$result2 = $connection->query($query2);
$what_category_id = mysqli_fetch_array($result2);
$connection->query("INSERT INTO places_a_categories VALUES ('$places_no', '$what_category_id')");
}
}
if ($connection->query("INSERT INTO places VALUES (NULL, 0, 0, 0, '$name', '$wysokosc', '$zajawka', '$zatloczenie', '$data_dodania', '$data_edycji', '$szer_geo', '$dlu_geo', '$tytul', '$opis', '$adres', '$tresc')"))
{
echo "Test!";
}
else
{
throw new Exception($connection->error);
}
}
Okay, explanations:
The part which inserts data to the table PLACES works just fine. It
adds data to the database according to what user has added in a form.
No help needed here.
Because of the before-mentioned automation of
table CATEGORIES I want to check how many of categories actually are
in the database. The first part of the code was supposed to do this.
with instruction FOR I assign every existing category to an array with a value equal to the name of the category in the database
then with instruction IF I want to add ass many rows of data to the table PLACES_A_CATEGORIES as many checkboxes have been checked
first value $places_no equals to id of the place which is being added to another table
second value $what_category_id looks for category_id in table PLACES_CATEGORIES where the name matches the current value got from the checkbox
And what are the results? Data is added to the table PLACES with no problem at all. But there is nothing added to the second table. Furthermore, I get no error message of any kind. It's probably some stupid error I just can't see... Any ideas? What have I done wrong?
I have a huge multistep form with data for multiple tables in mysql db. For every field my html is like-
input type="text" name="names" value="" // value set using php echo
On submit at php I am doing this for all the fields of my form-
$name=$_POST['names'] ?? ' '
to avoid unidentified index and unidentified variable
Then i update my first table and write log that its updated.
$query=mysqli_query($con,"UPDATE teacherpersonal set name='$name' ... where id=$id");
write_mysql_log("teacherpersonal updated", "facultydetails", $id).
I have defined write_mysql_log.
And similarly i update all the remaining tables with either the updated values or blank ("") values.
Since you can see that update query always executes even if the fields are not changed. Hence it is always logged that the tables are updated. But that's not what I want. I want to update only those fields in the table which are changed and remaining stay intact and log only those tables which are thus updated. Many tables won't be updated this way as the user might change only few details.
Using jquery and php.
My write_mysql_log is
function write_mysql_log($message, $db, $faculty_id)
{
$con=mysqli_connect("localhost","root","");
mysqli_select_db($con,"facultydetails");
// Construct query
$sql = "INSERT INTO my_log (message, faculty_id) VALUES('$message', '$faculty_id')";
$query=mysqli_query($con, $sql);
// Execute query and save data
if($query) {
echo 'written to the database';
}
else {
echo 'Unable to write to the database';
}
}
This you can achieve in 2 different ways.
1) With the help of jQuery check the values which are updated, post only those values to the php script
2)At the time of updating the check the current values with the updated one based on that criteria update the db tables.
solution 1 is less time taking process compare to the other.
You need to update only the user edited value, by doing this you can achieve it;
$oldvalue = array("username" => "green", "email" => "green#mail.com","dob" => "111");
$newvalue = array( "email" => "green#mail.com","dob" => "111","username" => "blue");
$updates = array_diff($newvalue, $oldvalue);
$implodeArray = implode(', ', $updates);
$sql = ("UPDATE user WHERE userID=$userID SET $implodeArray");
mysql_query($sql,$this->_db) or die(mysql_error());
mysql_close();
Output:
$updates = array_diff($newvalue, $oldvalue);
will have:
Array ( [username] => blue )
which is changed one
Ok after considering many options like-
create json object for old and new data and then compare and check which values changed and update that table and log it.
Or create a php array with old and new data and check diff then do the same (as suggested by Ram Karuppaiah)
Or a bad idea to have a flag on every input and then mark which ones have changed using onkeyup jquery event then try to update only those fields tables.
So finally what i did is that i let the form get submitted with all the data. As earlier i am taking the data in php as $name=$_POST['names'] ?? ' ' (blank if nothing is submitted or if something submitted then its value).
Before update statement in php, i am querying the table and comparing the database values with the values i got, if all same i dont do anything. If not then i update the table with the new values and log the change.
I populate a web form with rows of data. Some of the fields I need to be updatable so I put the value into a text field. MySQL query is:
SELECT * FROM results WHERE EventID = %s AND CompNo = %s", GetSQLValueString($colname_rsResults, "int"),GetSQLValueString($colname2_rsResults, "int"));
EventID and CompNo are passed in the URL.
Let's say the result is 50 rows. I want to be able to update the Name field (eg, make correction to the spelling), click a button and have the code update the database with any new values. It doesn't matter that most of the values will not change as this is a very infrequent operation.
I used to be able to do this in ASP but I can't seem to do in PHP.
This is the code I am using and I think it is completely wrong!!
if ((isset($_POST["JM_update"])) && ($_POST["JM_update"] == "form1")) {
$i = 0;
$j = $totalRows_rsResults;
while($i < $j)
$resultID=$_GET['ResultID'];
$vDelete=$_GET['Del'];
if ($vDelete == 1) {
$delSQL = sprintf("DELETE FROM Results WHERE ResultID=$resultID");
mysql_query($delSQL,$connFeisResults);
} else {
$name=$_GET['Name'];
$qual=$_GET['Qual'];
$updateSQL = sprintf("UPDATE results SET Name = ".$name{$i}.", Qual = ".$qual[$i]." WHERE ResultID=$resultID");
mysql_query($updateSQL, $connFeisResults);
$i++;
}
}
There is also a checkbox at the end of each row to check if I need that record deleted. That doesn't work either!!
I am using Dreamweaver CS6 and trying to adapt the update behaviours etc.
Any thoughts? Many thanks in advance.
It looks like you're missing an opening brace after your while statement.
--UPDATED
Also, check your sprintf statements -- they look wrong, and they look like they're writing the raw '$resultID' to the SQL String, instead of the value within it.
See how to do it here: http://www.talkphp.com/general/1062-securing-your-mysql-queries-sprintf.html
I have a submission script that I wrote in PHP. It is used by multiple surveys at our organization. The surveys are created by other users. When they submit to the script, PHP puts the data into the appropriate table in MySQL. The error that I run into sometimes is that the user(s) update the form. They add a field, or rename an input and the script doesn't account for it since it expects everything to be the same. So, I am trying to find a way to make it accomodate for when a new field is added. Here is what I have:
if( mysql_num_rows( mysql_query("SHOW TABLES LIKE '".$survey."'"))){
echo "table exists";
$sql = "SELECT * FROM " . $survey . ";";
$result = mysql_query($sql)
or die(mysql_error());
$i=0;
while($row = mysql_fetch_row($result));{
echo $row[0];
foreach($_POST as $k => $v){
$i++;
if($k != $row[$i]){
$query = "ALTER TABLE " . $survey . " ADD " . $k . " VARCHAR(100);";
mysql_query($query)
or die(mysql_error());
}
}
}
}
I am used to doing while loops in JS, so I don't know if using i works here (actually, I know it doesn't work... because it doesn't work...). What I am trying to say is that if a key doesn't match a current field name, then add it to the table. How can I return $row correctly?
When I submit to the script it says:
Duplicate column name 'V4'
I have echo $row[0] but it returns a 1. Which is the is the int used in the primary key for the for the first record.
You have a ; at the end of your while loop declaration that shouldn't be there. Not sure if that is causing the problem as you don't say what the above code does do. Update the question if the ; is not the issue.
Your while loop declaration should look like this: while($row = mysql_fetch_row($result)) {
Also, as Marc B so diplomatically put it in a comment to your question, you should be escaping any user input that goes directly into a query.
The easiest way to do this is to use $survey = mysql_real_escape_string($survey), before your first use of $survey, as a start or switch to PDO/MySQLi and use input binding (prepared statements). Here are the prepared statements docs for PDO. More can, and should, be done to protect yourself, but the above is a good start.
I have a strange mysql-thing going on here, it is about the following code:
$res = mysql_query("SELECT * FROM users WHERE group='".$group."'");
if (mysql_num_rows($res)==1) {
$row = mysql_fetch_assoc($res);
$uid = $row['uid'];
$user_update = mysql_query("UPDATE fe_users SET group = 5 WHERE group='".$group."'");
return 'ok';
} else {
return 'not ok';
}
I am checking, if there is a user with the group = $group. If so, the group is updated to 5 and after that the string "ok" is returned, if no user with group=$group exists, as you can see the string "not ok" is returned.
This should be very easy, but the problem now is, that if there is a user with group=$group, the update is done correctly, but instead of returning "ok", php returns "not ok", as if the change from the update is been taken into account for the above executed select retroactively. I dont understand this. Any help would be really appreciated.
Thanx in advance,
Jayden
I think 'group' is a reserved keyword that you have used as a field name, change it or use like
$res = mysql_query("SELECT * FROM users WHERE `group`='".$group."'");
and
$user_update = mysql_query("UPDATE fe_users SET `group` = 5 WHERE `group`='".$group."'");
and you can use count($res)==1 instead of mysql_num_rows($res)==1 if it is a problem.
Reference: Mysql Reserved keywords.
I am not sure if this has any merit but try using this style in your SELECT and UPDATE commands: WHERE group='$group', without using string joins. Other than that I can't seem to see why you are getting an update and not being returned "ok".
You are checking if mysql_num_rows($res)==1, so you'll return ok if there is exactly one user on that group. If there are two or more users, it will return not ok. Probably not what you want, right? I think you should check if mysql_num_rows($res)>=1.
You might consider modifying the placement of your brackets, and changing your num_rows check, like so:
$res = mysqli_query("SELECT uid FROM users WHERE `group` ='".$group."'");
if (mysqli_num_rows($res)>0) {//there was a result
while($row = mysqli_fetch_assoc($res)){
// grab the user id from the row
$uid = $row['uid'];
// and update their record
$user_update = mysqli_query("UPDATE fe_users SET `group` = 5 WHERE `group`='".$group."'");
if(mysqli_num_rows($user_update)==1){
return 'ok, updated user';
} else {
// database error
return 'not ok, unable to update user record';
}
}//end while row
}else{
return 'No results were found for this group.';
}
By selecting just the column you want, you reduce the query's overhead. By comparing the initial result to 0 instead of 1, you allow for groups with many members. By wrapping the update function in a while loop, you can loop through all the returned results, and update records for each one. By moving the test that returns 'ok'/'not ok' to check for success on the update operation, you're able to isolate database errors. The final else statement tells you if no update operation was performed because there are no members of the group.
BTW, for future-compatible code, I recommend using mysqli, as the "mysql_query" family of PHP functions are officially deprecated. See http://www.php.net/manual/en/mysqli.query.php for a quick start, it's largely the same thing.