Update multiple rows with single query using MySQL and PHP - php

<?php
$userData = array();
while (anything to create a loop) {
$value1 = $result1_from_loop;
$value2 = $result2_from_loop;
$value3 = $result3_from_loop;
$userData[] = '("'.$value1.'", "'.$value2.'", "'.$value3.'")';
} // THIS ENDS THE WHLE OR FOR LOOP
$query = 'INSERT INTO users (data1,data2,data3) VALUES' . implode(',', $userData);
mysql_query($query);
?>
The above code works perfectly for inserting multiple records into table users as seen above and it's very fast as well.
However, I am trying to use the same method to update after going through a loop as before. I have no idea how to achieve this.
I want something like this:
<?php
$userData = array();
while (Loop statement) {
$value1 = $result1_from_loop;
$value2 = $result2_from_loop;
$value3 = $result3_from_loop;
$userData[] = '("'.$value1.'", "'.$value2.'", "'.$value3.'")';
} // This ends the WHLE or FOR loop
$query = 'UPDATE users SET(data1,data2,data3) VALUES' . implode(',',$userData) WHERE data2=$value2
mysql_query($query);
I know the above code is not close to correct, syntax is even wrong. I just pasted it to show the idea of what I want achieved. In the WHERE statement how will data2 get to know the value of each $value2?

UPDATE uses a different format to INSERT. For UPDATE, your code should look something like this:
$query = 'UPDATE users SET data1 = $userData[0], data2 = $userData[1], data3 = $userData[2] WHERE data2=$value2';
Although just as a note, using mysql_query is not advised as it is deprecated (and will be removed altogether in later PHP versions) and your code is vulnerable to SQL injection. At a minimum I'd recommend using mysqli_query instead and looking into using prepared statements.

Related

Simple sample query working update but skips the first condition

I have a php code that updates the value in 2 tables and I used left join. It works but it keeps on skipping the first condition and always enters the second condition. I have no idea on mysql injection so please advice if my code is prone to mysql injection.
elseif ($_POST['check'])
{
if ($row[typeofdog] = 'Labrador')
{
$id = $_POST['data'];
$count = count($id);
for($i=0;$i<$count;$i++)
{
$sql = "UPDATE animals LEFT JOIN treats ON animals.style = treats.style SET animals.bone = bone - treats.total, treats.status = 'Approved' WHERE treats.id='$id[$i]'";
$result = mysql_query($sql);
}
if($result){header("location:login_success.php");}
}
else
{
$id = $_POST['data'];
$count = count($id);
for($i=0;$i<$count;$i++)
{
$sql = "UPDATE animals LEFT JOIN treats ON animals.style = treats.style SET animals.chunks = chunks - treats.total, treats.status = 'Approved' WHERE treats.id='$id[$i]'";
$result = mysql_query($sql);
}
if($result){header("location:login_success.php");}
}
}
First, = is for assignment. == is for comparison.
Second, using the index typeofdog without quotes is incorrect. PHP explains why here.
Try this:
if ($row['typeofdog'] == 'Labrador')
If this doesn't work, then $row['typeofdog'] does not equal 'Labrador'. In that case, try echoing $row['typeofdog'] just before the conditional so you can see what is being compared.
Also, yes, you are at risk for sql injection. First step to fixing this: don't use mysql. Instead use mysqli or pdo and utilize prepared statements.

Updating MySQL DB with PHP

I'm using foreach to loop an array and update a MySQL database.
This is my code
foreach($result['getHiscore'] as $highScoreType => $highScoreValues){
$rank = $highScoreValues['rank'];
$lvl = $highScoreValues['lvl'];
$totalXp = $highScoreValues['totalxp'];
mysqli_query($con,"UPDATE Users SET Level("$highScoreType") = $lvl, Xp("$highScoreType") = $totalXp,
WHERE UserID= '1'");
}
i'm trying to conflate the word "level" with the contents of $highScoreType, the column titles in my DB are Leveloverall, Xpoverall, Levelattack, Xpattack and so on so i was planning on keeping the Level/Xp title constant and just changing the key.
This looks fine to me and when i tested the sql with pre-set values it updated fine, however using the variables doesn't update at all. I know that the variables are coming out of the array correctly as when i echo them inline with the foreach they print out in the correct format and order.
Is it my formatting thats the issue or am i doing missing something else?
If you echo the generated SQL query that should help you see any problems in the query.
It looks odd to me: UPDATE Users SET Level("$highScoreType") = $lvl
Shouldn't that just be UPDATE Users SET $highScoreType = $lvl ?
Be aware also that this sort of code is vulnerably to SQL injection attacks so always be wary of what could be in those variables.
To print the query do:
$query = "UPDATE Users SET Level("$highScoreType") = $lvl, Xp("$highScoreType") = $totalXp, WHERE UserID= '1'"
echo $query
mysqli_query($con, $query)

Building interactive WHERE clause for Postgresql queries from PHP

I'm using Postgresql 9.2 and PHP 5.5 on Linux. I have a database with "patient" records in it, and I'm displaying the records on a web page. That works fine, but now I need to add interactive filters so it will display only certain types of records depending on what filters the user engages, something like having 10 checkboxes from which I build an ad-hoc WHERE clause based off of that information and then rerun the query in realtime. I'm a bit unclear how to do that.
How would one approach this using PHP?
All you need to do is recieve all the data of your user's selected filters with $_POST or $_GET and then make a small function with a loop to concatenate everything the way your query needs it.
Something like this... IN THE CASE you have only ONE field in your DB to match with. It's a simple scenario and with more fields you'll need to make it so that you add the field you really need in each case, nothing too complex.
<?php
//recieve all the filters and save them in array
$keys[] = isset($_POST['filter1'])?'$_POST['filter1']':''; //this sends empty if the filter is not set.
$keys[] = isset($_POST['filter2'])?'$_POST['filter2']':'';
$keys[] = isset($_POST['filter3'])?'$_POST['filter3']':'';
//Go through the array and concatenate the string you need. Of course, you might need AND instead of OR, depending on what your needs are.
foreach ($keys as $id => $value) {
if($id > 0){
$filters.=" OR ";
}
$filters.=" your_field = '".$value."' ";
}
//at this point $filters has a string with all your
//Then make the connection and send the query. Notice how the select concatenates the $filters variable
$host = "localhost";
$user = "user";
$pass = "pass";
$db = "database";
$con = pg_connect("host=$host dbname=$db user=$user password=$pass")
or die ("Could not connect to server\n");
$query = "SELECT * FROM table WHERE ".$filters;
$rs = pg_query($con, $query) or die("Cannot execute query: $query\n");
while ($row = pg_fetch_row($rs)) {
echo "$row[0] $row[1] $row[2]\n";
//or whatever way you want to print it...
}
pg_close($con);
?>
The above code will get variables from a form that sent 3 variables (assuming all of them correspond to the SAME field in your DB, and makes a string to use as your WHERE clause.
If you have more than one field of your db to filter through, all you need to do is be careful on how you match the user input with your fields.
NOTE: I did not add it here for practical reasons... but please, please sanitize user input.. ALWAYS sanitize user input before using user controlled data in your queries.
Good luck.
Don't do string concatenation. Once you have the values just pass them to the constant query string:
$query = "
select a, b
from patient
where
($x is not null and x = $x)
or
('$y' != '' and y = '$y')
";
If the value was not informed by the user pass it as null or empty. In the above query the x = $x condition will be ignored if $x is null and the y = '$y' condition will be ignored if $y is empty.
With that said, a check box will always be either true or false. What is the exact problem you are facing?
Always sanitize the user input or use a driver to do it for you!
I have created a Where clause builder exactly for that purpose. It comes with the Pomm project but you can use it stand alone.
<?php
$where = Pomm\Query\Where::create("birthdate > ?", array($date->format('Y-m-d')))
->andWhere('gender = ?', array('M'));
$where2 = Pomm\Query\Where::createWhereIn('something_id', array(1, 15, 43, 104))
->orWhere($where);
$sql = sprintf("SELECT * FROM my_table WHERE %s", $where2);
$statement = $pdo->prepare($sql);
$statement->bind($where2->getValues());
$results = $statement->execute();
This way, your values are escaped and you can build dynamically your where clause. You will find more information in Pomm's documentation.

PHP, admins usersystem

I was wondering if you think this is possible:
Ok so I have a database storing usernames and I would like to echo the admins which are inside a file called admins.php IF they match the usernames inside the database so far I have got:
admins.php;
$admins = array("username","username2","username3");
and
$users="SELECT username from usrsys";
$query_users=mysql_query($users);
while loop here.
The while loop should hopefully echo the users which matches the admins.php file. I assume I should use something like (inarray()), but I am really not sure.
You should definitely use IN clause in your SQL to do this. Selecting everything from the table in order to determine in PHP if it contains the user names you're looking for makes no sense and is very wasteful. Can you imagine what would happen if you had a table of 1 million users and you needed to see if two of them were on that list? You would be asking your DBMS to return 1 million rows to PHP so that you can search through each of those names and then determine whether or not any of them are the ones you're looking for. You're asking your DBMS to do a lot of work (send over all the rows in the table), and you're also asking PHP to do a lot of work (store all those rows in memory and compute a match), unnecessarily.
There is a much more efficient and faster solution depending on what you want.
First, if you only need to know that all of those users exist in the table then use SELECT COUNT(username) instead and your database will return a single row with a value for how many rows were found in the table. That way you have an all or nothing approach (if that's what you're looking for). Either there were 3 rows found in the table and 3 elements in the array or there weren't. This also utilizes your table indexes (which you should have properly indexed) and means faster results.
$admins = array("username","username2","username3");
// Make sure you properly escape your data before you put in your SQL
$list = array_map('mysql_real_escape_string', $admins);
// You're going to need to quote the strings as well before they work in your SQL
foreach ($list as $k => $v) $list[$k] = "'$v'";
$list = implode(',', $list);
$users = "SELECT COUNT(username) FROM usrsys WHERE username IN($list)";
$query_users = mysql_query($users);
if (!$query_users) {
echo "Huston we have a problem! " . mysql_error(); // Basic error handling (DEBUG ONLY)
exit;
}
if (false === $result = mysql_fetch_row($query_users)) {
echo "Huston we have a problme! " . mysql_error(); // Basic error handling (DEBUG ONLY)
}
if ($result[0] == count($admins)) {
echo "All admins found! We have {$result[0]} admins in the table... Mission complete. Returning to base, over...";
}
If you actually do want all the data then remove the COUNT from the SQL and you will simply get all the rows for those users (if any are found).
$admins = array("username","username2","username3");
// Make sure you properly escape your data before you put in your SQL
$list = array_map('mysql_real_escape_string', $admins);
// You're going to need to quote the strings as well before they work in your SQL
foreach ($list as $k => $v) $list[$k] = "'$v'";
$list = implode(',', $list);
$users = "SELECT username FROM usrsys WHERE username IN($list)";
$query_users = mysql_query($users);
if (!$query_users) {
echo "Huston we have a problem! " . mysql_error(); // Basic error handling (DEBUG ONLY)
exit;
}
// Loop over the result set
while ($result = mysql_fetch_assoc($query_users)) {
echo "User name found: {$result['username']}\n";
}
However, I really urge you to reconsider using the old ext/mysql API to interface with your MySQL database in PHP since it is deprecated and has been discouraged from use for quite some time. I would really urge you to start using the new alternative APIs such as PDO or MySQLi and see the guide in the manual for help with choosing an API.
In PDO, for example this process would be quite simple with prepared statements and parameterized queries as you don't have to worry about all this escaping.
There's an example in the PDOStatement::Execute page (Example #5) that shows you just how to do use the IN clause that way with prepared statements... You can then reuse this statement in other places in your code and it offers a performance benefit as well as making it harder for you to inadvertently expose yourself to SQL injection vulnerabilities.
// Connect to your database
$pdo = new PDO("mysql:dbname=mydb;host=127.0.0.1", $username, $password);
// List of admins we want to find in the table
$admins = array("username","username2","username3");
// Create the place holders for your paratmers
$place_holders = implode(',', array_fill(0, count($admins), '?'));
// Create the prepared statement
$sth = $dbh->prepare("SELECT username FROM usrsys WHERE username IN ($place_holders)");
// Execute the statement
$sth->execute($admins);
// Iterate over the result set
foreach ($sth->fetchAll(PDO::FETCH_ASSOC) as $row) {
echo "We found the user name: {$row['username']}!\n";
}
Your PHP code even looks so much better with PDO :)
Just include admins.php file and use the next construction in your loop:
while ($row = mysql_fetch_array($users)) {
if (in_array($users[0], $admins))
echo $users[0];
}
Try this:
<?php
# include admins.php file that holds the admins array
include "admins.php";
# join all values in the admins array using "," as a separator (to use them in the sql statement)
$admins = join(",", $admins);
# execute the query
$result = mysql_query("
SELECT username
FROM usrsys
WHERE username IN ($admins)
");
if ($result) {
while ($row = mysql_fetch_array($result)) {
echo $row["username"] . "<br>";
}
}
?>
If your looking for syntax to pull in only the users from your $admins array then you could use something like:
$users="SELECT username FROM usrsys WHERE username IN ('".join("','",$admins)."')";
Where the php function JOIN will print username,username2,username3. Your resulting MySQL statement will look like:
SELECT username FROM usrsys WHERE username IN ('username','username2','username3')
Alternatively, if your looking to iterate through your $query_vars array and separate your admins from non-admins then you could use something like:
<?php
while($row = mysql_fetch_assoc($query_users)){
if(in_array($row['username'],$admins)){
//do admin stuff here
}else{
//do NON-admin stuff here
}
}?>

Append 2 Mysql rows

I have a two step registration, one with vital data, like email username and password, and a second optional one with personal info, like bio, eye color, etc.. i have 2 exec files for these, the first ofc writes the data in the first part of the database, leaving like 30 columns of personal data blank. The second one does another row, but with the vital data empty now.. I would like to append, or join these two rows, so all the info is in one row..
Here is the 2nd one
$qry = "UPDATE `performers` SET `Bemutatkozas` = '$bemuatkozas', `Feldob` = '$feldob', `Lehangol` = '$lehangol', `Szorzet` = '$szorzet', `Jatekszerek` = '$jatek', `Kukkolas` = '$kukkolas', `Flort` ='$flort', `Szeretek` = '$szeretek', `Utalok` = '$utalok', `Fantaziak` = '$fantaziak', `Titkosvagyak` = '$titkos_vagyak, `Suly` = '$suly', `Magassag` = '$magassag', `Szemszin` = '$szemszin', `Hajszin` = '$hajszin', `Hajhossz` = '$hajhossz', `Mellboseg` ='$mellboseg', `Orarend` = '$orarend', `Beallitottsag` = '$szexualis_beallitottsag', `Pozicio` = '$pozicio', `Dohanyzas` = '$cigi', `Testekszer` = '$pc', `Tetovalas` ='$tetko', `Szilikon` ='$szilikon', `Fetish1` = '$pisiszex', `Fetish2` = '$kakiszex', `Fetish3` = '$domina', `Testekszerhely` = '$pchely', `Tetovalashely` = '$tetkohely', `Csillagjegy` = '$csillagjegy', `Parral` = '$par', `Virag` = '$virag' WHERE `Username` ='" . $_POST['username']. "'";
$result = #mysql_query($qry);
//Check whether the query was successful or not
if($result) {
header("location: perf_register_success.php");
exit();
I'm not sure if $_POST works here. I have the form, then the exec of that form, which works, then this form, and this is the exec of that.. Anyway I always get "query failed" message, which is in the else statement of the 'if' i'm using. What am i doing wrong?
Thanks!
The correct syntax for UPDATE is as follows:
UPDATE table SET columnA=valueA, columnB=valueB WHERE condition=value
(documentation here)
Thus, your query should look like the following:
$qry = "UPDATE performers SET Bemutatkozas = $bemuatkozas, Feldob = $feldob, Lehangol = $lehangol [...] WHERE Username ='" . $_POST['username']. "'
You'll have to replace [...] with all your values (that's gonna take some time) but hopefully you get the pattern.
Other than that there are a number of things you should improve/change in your code but I'll just point you to jeroen answer in this question since he pretty much covers it all.
You want UPDATE instead of INSERT for your second query.
Apart from that you really need to fix that sql injection error, preferably by switching to PDO or mysqli in combination with prepared statements. The mysql_* functions are deprecated.
And whatever solution you take, you need to add proper error handling, suppressing errors is wrong, especially when you try to fix a problem but even in a production site, errors need to be logged, not ignored.

Categories