2

I have table with columns something like this:

table(INT id, serial, data)

And I want to create following SELECT command:

SELECT * FROM table WHERE serial IN (list-of-serial)

But problem is that when I add more than one value into list-of-serial, I get empty query.

For example:

id serial
1  1234
2  5678
3  1234
4  9012
5  1234
6  5678
7  9012

SELECT * FROM table WHERE serial IN ('1234','9012')

In this form, it works, but I need to convert it into C# query.

string file="my-sqlite-database";
SQLiteConnection database = new SQLiteConnection($@"URI=file:{file}");
database.Open();
SQLiteCommand C = new SQLiteCommand("SELECT * FROM table WHERE serial IN (@serials)", database);
C.Parameters.AddWithValue("@serials","('1234','9012')");
C.Prepare();
SQLiteDataReader R = C.ExecuteReader();
While(R.Read()){} // 0 rows

What am I doing wrong? I have tried passing string arrays, string with and without quotes, no difference.

1
  • It won't work like this. This will essentially look for a row where the serial is literally ('1234','9012') Commented Nov 18, 2021 at 9:27

2 Answers 2

3

Unless you inject it directly into the SQL statement, a parameter will only ever be interpreted as a literal value. So it will be looking for a single string matching ('1234','9012'). And injection is a bad idea, which you should generally avoid.

Unfortunately, SQLite does not support Table-Valued parameters. So you need to use multiple parameters here:

string file = "my-sqlite-database";
var parms = new string[]{"1234", "9012"};
using (SQLiteConnection database = new SQLiteConnection($@"URI=file:{file}"))
using (SQLiteCommand C = new SQLiteCommand("", database))
{
    C.Parameters.AddRange(parms.Select((p, ind) => new SqliteParameter("@p" + ind, p)));
    C.CommandText = $@"
SELECT *
FROM table
WHERE serial IN ({string.Join(",", parms.Select((p, ind) => "@p" + ind))})
";
    database.Open();
    C.Prepare();
    using (SQLiteDataReader R = C.ExecuteReader())
    {
        while(R.Read())
        { //do something
        }
    }
}

Dapper can do the above natively, so you may want to look at that.

Note also correct use of using blocks to dispose.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, it works! And is probably most safe way to pass variables.
0

Just a hunch, I might be wrong.
I have never used C# but I feel like what is happening might be that "('1234','9012')" is counted as a string.
Did you try making an array and passing the array instead?

1 Comment

Yes, it does not work like this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.