dbCommand.Append синтаксическая ошибка преобразования EQUALS в LIKE с @parameter - PullRequest
0 голосов
/ 27 апреля 2020

У меня есть. NET C# веб-форма. CodeBehind забирает некоторую запись в текстовом поле, чтобы добавить к оператору выбора для используемых текстовых полей. Вот текстовые поля ASP:

<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>

Вот (текущая неправильная версия) сторона сервера:

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);
}

Поэтому я хочу преобразовать имя и фамилию, добавленные в LIKE вместо РАВНЫХ. Оставив пока FIRSTNAME в одиночестве, я дурачился с LASTNAME и не добился успеха.

Может кто-нибудь дать мне исправление синтаксиса для использования как в команде добавления, пожалуйста?

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

Спасибо

1 Ответ

1 голос
/ 27 апреля 2020

Это не то, что вы ожидаете:

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

Конкатенация строк отключена, и @txtLast в качестве идентификатора в C# вместо части SQL. Символ @ - C# используется для добавления префиксов к идентификаторам, если они могут соответствовать ключевому слову. У вас есть текстовое поле с именем txtLast, что делает этот код легальным с неявным преобразованием в строку.

В результате, если он даже скомпилирует результирующее выражение LIKE, вероятно, оно недопустимо в SQL. Вы, вероятно, в конечном итоге получите условие в SQL, например:

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

Помимо имени типа вместо текстового значения, в нем также отсутствуют необходимые одинарные кавычки.

Возможно, вы хотели это:

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

Или это:

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

Кроме того, вам следует рассмотреть возможность предоставления всей информации о типе для ваших параметров. Если вы этого не сделаете, ADO. Net осталось угадать по типам и длинам. Это имеет тенденцию предполагать NVARCHAR и 50 (или точную длину текста). Любое из этих допущений может вызвать серьезные проблемы с производительностью, если они ошибочны, с точки зрения принудительного пропуска индекса (который может быть ОГРОМНЫМ) или преобразования для каждой строки для каждой строки в таблице (которая также может быть огромной).

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);
}

Или, короче:

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

Специально для цифр и дат это может быть важно. Я бы написал Badge_ID раздел так:

if (!string.IsNullOrEmpty(txtBadge.Text))
{
    sbCommand.Append(" AND a.BADGE_ID=@txtBadge");
    cmd.Parameters.Add("@txtBadge", SqlDbtype.Int).Value = int.Parse(txtBadge.Text);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...