I have this question about the MySqlParameter from the .NET connector.
I have this query:
SELECT * FROM table WHERE id IN (@parameter)
I don't think there's a way you can add them like that, but perhaps you could iterate through the list and generate the query dynamically.
For example:
var intArray = new List<int>(){1,2,3,4};
if (intArray.Count > 0) {
var query = "SELECT * FROM table WHERE id IN (";
for (int i = 0; i < intArray.Count; i++) {
//Append the parameter to the query
//Note: I'm not sure if mysql uses "@" but you can replace this if needed
query += "@num" + i + ",";
//Add the value to the parameters collection
...connection.Command.Parameters.AddWithValue("num" + i, intArray[i]);
}
//Remove the last comma and add the closing bracket
query = query.Substring(0, query.Length - 1) + ");";
//Execute the query here
}
This way, you could even use a differently typed list and still reap the benefits of parameterized queries. However, I don't know if there would be performance issues with larger lists but I suspect that would be the case.
when i pass it to the MySqlParameter and this is recognized as a string, it puts in the sql query like "1\,2\,3\,4" and this do not return the expected values.
I ran into this last night. I found that FIND_IN_SET works here:
SELECT * FROM table WHERE FIND_IN_SET(id, @parameter) != 0
...
intArray = new List<int>(){1,2,3,4};
conn.Command.Parameters.AddWithValue("parameter", string.Join(",", intArray));
Apparently this has some length limitations (I found your post looking for an alternate solution), but this may work for you.
Based on the Richard answer, I came up with a similar approach avoiding the SQL Injection:
private MySqlCommand GetCommandWithIn(string sql, string sqlParam, ICollection<string> list)
{
var command = new MySqlCommand(string.Empty, connection);
var i = 0;
var parameters = new List<string>(list.Count);
foreach (var element in list)
{
var parameter = $"p{i++}";
parameters.Add($"@{parameter}");
command.Parameters.AddWithValue(parameter, element);
}
command.CommandText = sql.Replace(sqlParam, string.Join(',', parameters));
return command;
}
And you can call it with:
var types = new List<string> { "Type1", "Type2" };
var sql = "SELECT * FROM TABLE WHERE Type IN (@Type)"
using var command = GetCommandWithIn(sql, "@Type", types);
Remember to check for empty list in order to avoid the IN ()
.
Parameters don't work with IN. I have always embedded such things as a string in the query itself. While that is generally considered bad form because SQL injection, if you are constructing the query from a strongly typed numeric list, then there should be no possibility of any external input corrupting it in a meaningful way.
As I know you cannot provide any array as a parameter to prepared statement. IN() doesn't support parameters as an array.
You have a few options here (in order of preference):
The data has to come from somewhere: either your database, user action, or machine-generated source.
If it's created by the user, add it to a separate table on each individual user action, and then use a sub query.
An example of this is a shopping cart. A user might select several items to purchase. Rather than keep these in the app and need to add all the items to an order in one go when they check out, add each item to a table in the db as the user selects or changes it.
The definitive (and I mean definitive) work on the subject is here:
http://www.sommarskog.se/arrays-in-sql.html
The article long, but in a good way. The author is a sql server expert, but the concepts on the whole apply to MySQL as well.