I get SQLite.SQLiteException: \'no such column: osborne\' when I run this code. osborne is my search term, not the column. The column is LastName. Here is the queryasync code
The problem is caused because you tried to concatenate the query string with a variable to get the final query. What you ended up was this SQL query:
SELECT * FROM [DataItem] WHERE [LastName] = Potato
Which is clearly invalid. It could be worse though. What if a malicious user passed 1; drop table DataItem;#
? That's how SQL injection attacks work.
You should never use string concatenation to pass values to a query. No amount of quoting is going to fix this problem either - what if someone is named O'Reilly
? Quoting won't prevent a hacker from entering Robert; drop table Students;--
. Look at Bobby Tables
The correct and safe way is to use parameterised queries (aka server-bound parameters). Parameters aren't string replacements. They're sent alongside the query to the database, preserving their type, precision etc. They allow you to send eg a decimal number or date as a strongly-typed decimal
or DateTime
and never worry about string formats and separators.
I suspect you used SQLite-net. The package's Github page shows how to use parameterised queries in this case, by using ?
:
return Database.QueryAsync<DataItem>("SELECT * FROM [DataItem] WHERE [LastName] = ?", s);
?
specifies a positional (ie unnamed) parameter. The parameter values you pass after the query text are used as the values for each ?
parameter, in the order they appear
you need to delimit string parameters in SQL queries
return Database.QueryAsync<DataItem>
($"SELECT * FROM [DataItem] WHERE [LastName] = '{s}'");
as pointed out in the comments, parameterized queries are more secure
return Database.QueryAsync<DataItem>
("SELECT * FROM [DataItem] WHERE [LastName] = ?", s);