11

I can get the result I expect by entering this in LINQPad:

SELECT * FROM WorkTable WHERE WTName LIKE "DSD__20090410014953000%"

(it shows me the record which has a WTName value of DSD__20090410014953000.xml")

But trying to do this programmatically is proving trying. I tried:

const string qry = "SELECT SiteNum FROM WorkTable WHERE WTName LIKE @wtName%";
using (SQLiteConnection con = new SQLiteConnection(HHSUtils.GetDBConnection()))
{
    con.Open();
    SQLiteCommand cmd = new SQLiteCommand(qry, con);
    cmd.Parameters.Add(new SQLiteParameter("wtName", tableName));
    siteNum = Convert.ToInt32(cmd.ExecuteScalar());
}

...but it causes the app to crash, and my log file tells me why:

Message: From application-wide exception handler: System.Data.SQLite.SQLiteException: SQL logic error or missing database
near "%": syntax error

So maybe it thinks the query parameter is named "wtName%" instead of "wtName"; but separating the parameter and the "whatever" opertor ("%") with a space doesn't work, either.

I could go retro/kludgy by just embedding the query parameter into the string like so:

const string qry = String.Format("SELECT SiteNum FROM WorkTable WHERE WTName LIKE {0}%", tableName);

...and doing without the query parameter altogether, but I'm afraid if I did that Troy Hunt would show up at my house and flail me with a bedrail while railing about SQL Injection.

How can I get my data and simultaneously write safe code?

Dharman
  • 30,962
  • 25
  • 85
  • 135
B. Clay Shannon-B. Crow Raven
  • 8,547
  • 144
  • 472
  • 862

3 Answers3

17

The wildcard % should be added to the parameter value, not to the parameter name

const string qry = "SELECT SiteNum FROM WorkTable WHERE WTName LIKE @wtName";
using (SQLiteConnection con = new SQLiteConnection(HHSUtils.GetDBConnection()))
{
    con.Open();
    SQLiteCommand cmd = new SQLiteCommand(qry, con);
    cmd.Parameters.Add(new SQLiteParameter("@wtName", tableName + "%"));
    siteNum = Convert.ToInt32(cmd.ExecuteScalar());
}

And, I am not sure if it matters here, but, usually, I insert the parameter name with the exact name used in the placeholder ( @wtName )

Steve
  • 213,761
  • 22
  • 232
  • 286
9

Easiest way to do this is to use '||'

Use :

const string qry = "SELECT SiteNum FROM WorkTable WHERE WTName LIKE @wtName || '%' ";

Instead Of:

const string qry = "SELECT SiteNum FROM WorkTable WHERE WTName LIKE @wtName%";
Kas
  • 3,747
  • 5
  • 29
  • 56
-2

Try defining query like this:

const string qry = "SELECT SiteNum FROM WorkTable WHERE WTName LIKE @wtName + '%'";
Dragan
  • 13
  • 3
  • Didn't try on SQLite but it works on SQL Server for sure. I copied it from existing project. – Dragan Jan 22 '15 at 23:53
  • The concatenation operator for strings in SQLite is || so you should write `@wtName || '%'` Still I believe that this is too error prone and not portable – Steve Jan 23 '15 at 00:08
  • @Dragon your answer is valid for SQL Server but not for SQLite , As I have answred in SQLite you must use '||' instead of '+' – Kas Aug 31 '15 at 13:22