Reputation: 43
I have a c# List intlist that contains (1,2,3,4,5)
I have a TABLE in a Sqlite db that also contains a int COLUMN with (1,2,3,4,5) as well as other fields
If I run a select using sqlite connection in c# like:
"SELECT COLUMN, COLUMN2 from TABLE where COLUMN in" + ('1','2','3','4','5');
it executes in < .001 sec But it requires me to type each value into the statement as above, when I already have that data in a list
So instead if I iterate over the list and run the same query like:
foreach (int i in intlist) {
"SELECT COLUMN, COLUMN2 from TABLE where COLUMN = " + i;
}
It runs 5 separate selects and takes > 1 sec
Obviously over large data sets this is amplified to the point it becomes unusable to iterate over and run all those selects. If I have 2,000 ints for example. I have tried batching the selects in transactions and it doesn't speed it up at all.
Is there some other way to iterate over a c# list and use values in that list in a Sqlite select? So I don't have to type them all in manually and can take advantage of the fact I already have the values in a list?
Upvotes: 0
Views: 490
Reputation: 216348
You should use a loop but to create the parameters required by your command. Something like these lines
List<int> intList = new List<int> {1,2,3,4,5};
string cmdText = "SELECT COLUMN, COLUMN2 from TABLE where COLUMN in({0})";
List<SQLiteParameter> prms = new List<SQLiteParameter>();
List<string> placeholders = new List<string>();
int x = 1;
foreach (int n in intList)
{
prms.Add(new SQLiteParameter {ParameterName = "@p" + x, DbType = DbType.Int32, Value = n});
placeholders.Add("@p" + x);
x++;
}
cmdText = string.Format(cmdText, string.Join(",", placeholders));
// At this point your command text looks like
// SELECT COLUMN, COLUMN2 from TABLE where COLUMN in(@p1,@p2,@p3,@p4,@p5)
using(SQLiteConnection con = new SQLiteConnection("Data Source=|DataDirectory|\\mydb.db"))
using(SQLiteCommand g = new SQLiteCommand(cmdText, con))
{
con.Open();
g.Parameters.AddRange(prms.ToArray());
SQLiteDataReader reader = g.ExecuteReader();
....
}
However I am not very comfortable with this solution if your number of parameters starts climbing. You talk about 2000 values for the IN clause and if this is true I cannot be sure of the performances, not just for this solution, but also the whole performances of an IN clause with so many values. Probably the approach mentioned by Crowcoder in its comment can be another solution.
Upvotes: 2