I have a variable, $ids
It is a , separated string so it can be $ids = "1" or $ids = "1, 3, 7, 8"
What i want to do is update the database based on these values so i have :
$query = "UPDATE Fields SET Value = '1' WHERE Id IN '$ids'";
And also:
$query = "UPDATE Fields SET Value = '1' WHERE Id '$ids'";
What is the best way to update the database, should i split the string in to an array, and then do a for each loop? or is there a better way?
Save the fact that it's wide open to SQL Injection, this line works for one or many id's:
$query = "UPDATE Fields SET Value = '1' WHERE Id IN ($ids)";
Now, to keep yourself from SQL Injection attacks, which is obviously up to you, you'd want to explode that array and send multiple update statements like this:
$query = "UPDATE Fields SET Value = '1' WHERE Id = :Id";
There's nothing inherently wrong with using an IN clause here. Any WHERE clause works for an UPDATE statement. You'll just want to treat the numbers as a list of values instead of a string. Something like this:
$query = "UPDATE Fields SET Value = '1' WHERE Id IN ($ids)";
The really important part is how you get the $ids value into the query in the first place. You don't show that in the question, but you'll want to make sure you're not opening yourself to a SQL injection vulnerability. Make sure you're properly sanitizing inputs and using prepared statements. How prepared statements handle lists of values vs. individual values is up to the data access technology being used.
Use this query:
$query = "UPDATE Fields SET Value = '1' WHERE Id IN ($ids)";
Where $ids should be formatted als 1,2,3,4. Don't forget to check them before execution (SQL Injection).
Related
I would like to get the value of a column, add a string to it, then update the column with the new value, and repeat this for every element of an array. I would like to use prepared statements, so my dream-code (which wouldn't work, I know) would be:
$getcolumn = $link->prepare("SELECT `column` FROM `table` WHERE `id`=? LIMIT 1");
$getcolumn->bind_param("i", $a_value);
$updatecolumn = $link->prepare("UPDATE `table` SET `column`=? WHERE `id`=? LIMIT 1");
$updatecolumn->bind_param("si", $newcolumnvalue, $a_value);
foreach($array as $a => $a_value) {
$getcolumn->execute();
$getcolumn->bind_result($columnvalue);
$getcolumn->fetch();
$newcolumnvalue = $columnvalue.$addedstring;
$updatecolumn->execute();
}
$getcolumn->close();
$updatecolumn->close();
However, for it to work, I should close $getcolumn before executing $updatecolumn. But if I close $getcolumn inside the foreach loop, it won't be repeated for all the elements of the array. So how do I write this in a way that works, using prepared statements? Thank you in advance.
Just like the comments above, I'd suggest another way and use CONCAT of MySQL built-in function instead of fetching all the rows from the first prepare:
$updatecolumn = $link->prepare("UPDATE `table` SET `column` = CONCAT(`column`, ?) WHERE id = ?");
$updatecolumn->bind_param("si", $addedstring, $a_value);
$updatecolumn->execute();
It just eliminates the first step that fetches the rows, this just updates the columns pertinent to that ID and concatenating the current columns value to that added string that you want.
I've two 3 variable and that used in $sql string
$bikeid = xxxxx
$st_char = column name
$st_tab = table name
I've coded out like this
$sql = "select $st_char
from $st_tab
where bike_id like '$bike_id'";
And like this
$sql = "select ".$st_char."
from dbo.".$st_tab."
where bike_id like ".$bike_id;
To select data from my database,the result is the same,they can get data from database
My question is which one is right and which one is wrong
if none wrong which one is better and why ?
Thanks
Both are bad because they are vulnerable to SQL injection.
There are also potential performance gains from using prepared statements. So at the very least, your query should look like:
select $st_char from $st_tab where bike_id like :bike_id
Unfortunately, you can't use parameters in certain situations, like column and table names. In this case you will need to do manual string concatenation, but whitelist allowed input. For example:
$allowed_cols = array('col1', 'col2', 'col3');
$allowed_tables = array('t1', 't2', 't3');
if(in_array($st_char, $allowed_cols, true) && in_array($st_tab, $allowed_tables, true))
{
$query = "select $st_char from $st_tab where bike_id like :bike_id";
// perform execution here
}
else
{
// invalid or malicious input
}
You may also want to wrap the table/column names in square brackets ([]) to avoid conflicts with any reserved keywords:
$query = "select [$st_char] from [dbo].[$st_tab] where bike_id like :bike_id";
Can I have some advice on where I'm going wrong with this Query?
$entry_id = '1';
$accident_road = $form_data[58]["id"]; //print_r returns "116"
$accident_road_array = $wpdb->get_results(
"SELECT id FROM wp_rg_lead_detail
WHERE field_number = '$accident_road'
AND 'lead_id' = '$entry_id' ",
ARRAY_A);
print_r returns 'Array()'
I assume lead_id is a field in DB so you don't need quotes for it:
AND lead_id = '$entry_id'
You're also going wrong by putting variables directly into the query, you make your app vulnerable to SQL injections. consider using prepared statements.
you set values in variable
$accident_road
while down there in query you used
'$accident_road_exp'
cross check this one man
I'm trying to count all of the rows from an item list where the id matches a user input. I am switching all of my code from mysql to PDO as I have learned it is much better.
The code below is what I found to work in my situation.
$id = '0';
$sql="SELECT count(*) FROM item_list WHERE item_id = $id";
$data=$connMembers->query($sql)->fetchcolumn();
echo $data;
However, It is not safe for a live site due to sql injections.
I want to know how can I change it to work whare it sanatizes the user input.
I would prefer using a prepare and execute functions so the variables are kept seperately.
So is there something I can do?
This is where you start binding parameters. I prefer to do it using ? and one array for inputs.
Assuming $connMembers is your PDO object:
$sql="SELECT COUNT(*) FROM item_list WHERE item_id = ?";
$input=array($id); //Input for execute should always be an array
$statement=$connMembers->prepare($sql);
$statement->execute($input);
$data=$statement->fetchObject();
var_dump($data);
To add more variables to your sql, just add another ? to the query and add the variable to your input.
$sql="SELECT COUNT(*) FROM item_list WHERE item_id = ? AND item_name=?";
$input=array($id, $name); //Input for execute should always be an array
$statement=$connMembers->prepare($sql);
$statement->execute($input);
$data=$statement->fetchObject();
var_dump($data);
OR you can use bindParam:
$sql="SELECT COUNT(*) FROM item_list WHERE item_id = :itemID";
$statement=$connMembers->prepare($sql);
$statement->bindParam(':itemID', $id);
/*Here I am binding parameters instead of passing
an array parameter to the execute() */
$statement->execute();
$data=$statement->fetchObject();
var_dump($data);
I have written a php script that returns an arbitrary number of specific ids (which are in the format of numbers) in an array. I would like to make a new query that selects each row from a table that belongs to each id. I know i can do 1 query to get one row with the matching id. But i would like to do this all in one query. Here is my code:
$id = array(1,4,7,3,11,120); // The array containing the ids
$query = mysql_query("SELECT *
FROM posts
WHERE id = '$id[0]'");
// I would like to Do this for each id in the array and return it as one group of rows.`
I think you want the IN clause:
$idList = implode(",", $id);
SELECT *
FROM posts
WHERE id IN ( $idList );
The implode() function will turn your array of numbers into a comma-separated string of those same values. When you use it as part of an IN clause, it tells the database to use those values as a lookup table to match id against.
Standard Disclaimer/Warning:
As with any SQL query, you really shouldn't be directly concatenating variables into the query string. You're just opening yourself up to SQL injection. Use prepared/parameterized statements instead.
Use PHP's implode function to convert the array into a comma separated value string.
Then, you can use the SQL IN clause to run a single SQL statement containing the values associated with the ids you captured from PHP:
$id = array(1,4,7,3,11,120);
$csv = implode(',', $id);
$query = sprintf("SELECT *
FROM posts
WHERE id IN (%s)",
mysql_real_escape_string($csv));
$result = mysql_query($query)
I omitted the single quotes because they aren't necessary when dealing with numeric values in SQL. If the id values were strings, each would have to be encapsulated inside of single quotes.
What you want is SQL's IN clause.
SELECT * FROM posts WHERE id IN (1, 4, 7, 11, 120)
In PHP, you'll probably want something like:
$query = mysql_query(sprintf("SELECT * FROM posts WHERE id IN (%s)", implode(',', $id)));
Obviously, that's assuming you know you have integer values for $id, and that the values for $id didn't come from the user (that is, they should be sanitized). To be safe, you really ought to do something like:
$ids = implode(',', array_map('mysql_real_escape_string', $id));
$query = mysql_query("SELECT * FROM posts WHERE id IN ($ids)");
And if $id is dynamically generated, don't forget to put something in that IN clause, because SELECT * FROM foo WHERE bar IN () will give you an error. I generally make sure to set my IN-clause variables to 0, since IN (0) is good, and primary keys are pretty much never 0.