0

I have a .NET C# webform. The CodeBehind picks up some textbox entry to append to a select statement for the txtboxes that are used. Here are the ASP textboxes:

<asp:TextBox ID="txtBadge" runat="server" CssClass="txtBadgeStyle"></asp:TextBox>    
<asp:TextBox ID="txtFirst" runat="server" CssClass="txtFirstStyle"></asp:TextBox>
<asp:TextBox ID="txtLast" runat="server" CssClass="txtLastStyle"></asp:TextBox>

Here's the (current wrong version) server side:

StringBuilder sbCommand = new StringBuilder("SELECT a.BADGE_ID, a.FIRSTNAME, a.LASTNAME, a.TITLE, b.deptname, CASE WHEN a.ACTIVE=1 THEN 'Yes' ELSE 'No' END FROM XA_EMPMAS a left join dept_master b on b.deptnum = a.deptnum where 1 = 1");

if (string.IsNullOrEmpty(txtBadge.Text) == false)
{
    sbCommand.Append(" AND a.BADGE_ID=@txtBadge");
    SqlParameter param = new SqlParameter("@txtBadge", txtBadge.Text);
    cmd.Parameters.Add(param);
}

if (string.IsNullOrEmpty(txtFirst.Text) == false)
{
    sbCommand.Append(" AND a.FIRSTNAME=@txtFirst");
    SqlParameter param = new SqlParameter("@txtFirst", txtFirst.Text);
    cmd.Parameters.Add(param);
}

if (string.IsNullOrEmpty(txtLast.Text) == false)
{
    sbCommand.Append(" AND a.LASTNAME like " + @txtLast + "%");
    SqlParameter param = new SqlParameter("@txtLast", txtLast.Text);
    cmd.Parameters.Add(param);
}

So I want to convert the first name and last name appends to LIKE instead of EQUALS. Leaving FIRSTNAME alone for now, I've been fooling around with LASTNAME and haven't had any success.

Can someone give me the syntax correction for using like in the append command please?

sbCommand.Append(" AND a.LASTNAME like " + @txtLast + "%");

Thanks

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
user1349089
  • 127
  • 6
  • 15
  • Does this answer your question? [Use of SqlParameter in SQL LIKE clause not working](https://stackoverflow.com/questions/665129/use-of-sqlparameter-in-sql-like-clause-not-working) – devNull Apr 27 '20 at 18:47
  • Thanks @devNull. No I started out with that thread (and one other) but couldn't quite get the quotes straightened out correctly. Also the OP in that post was chasing both sides LIKE '%@text%'. I was only chasing the backend LIKE '@text%'. Thanks though. – user1349089 Apr 27 '20 at 19:14

1 Answers1

1

This is not doing what you expect:

sbCommand.Append(" AND a.LASTNAME like " + @txtLast + "%");

The string concatenation is off, leaving @txtLast as an identifier in C#, rather than part of the SQL. The @ character is C# is used to prefix identifiers if they might match a keyword. You have a textbox named txtLast, making this code legal with an implicit conversion to string.

As a result, if it even compiles the resulting LIKE statement is probably not legal in SQL. You're probably ending up with a condition in the SQL like this:

AND a.LaSTNAME like System.Web.UI.WebControls.Textbox%

Aside from the type name instead of the text value, this is also missing the required single quotes.

You probably wanted this:

sbCommand.Append(" AND a.LASTNAME like @txtLast + '%'");

Or this:

sbCommand.Append(" AND a.LASTNAME like @txtLast");
SqlParameter param = new SqlParameter("@txtLast", txtLast.Text + "%");

Additionally, you should consider supplying all of the type information for your parameters. If you don't, ADO.Net is left to guess at the types and lengths. It tends to assume NVARCHAR and 50 (or the exact length of the text). Either of those assumptions can cause big performance problems when they are wrong, in terms of forcing index misses (which can be HUGE) or per-row conversions for every row in the table (which can also be huge).

if (!string.IsNullOrEmpty(txtLast.Text))
{
    sbCommand.Append(" AND a.LASTNAME like @txtLast + '%'");
    SqlParameter param = new SqlParameter("@txtLast", SqlDbtype.NVarChar, 50);
    param.Value = txtLast.Text;
    cmd.Parameters.Add(param);
}

Or, shorter:

if (!string.IsNullOrEmpty(txtLast.Text))
{
    sbCommand.Append(" AND a.LASTNAME like @txtLast + '%'");
    cmd.Parameters.Add("@txtLast", SqlDbType.NVarChar, 50).Value = txtLast.Text;
}

Especially for numbers and dates this can be important. I would write the Badge_ID section like this:

if (!string.IsNullOrEmpty(txtBadge.Text))
{
    sbCommand.Append(" AND a.BADGE_ID=@txtBadge");
    cmd.Parameters.Add("@txtBadge", SqlDbtype.Int).Value = int.Parse(txtBadge.Text);
}
Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794