Передать «РАВНО НУЛЮ» через параметр

#c# #wpf #sqlite

#c# #wpf #sqlite

Вопрос:

У меня есть 5 текстовых полей:

 <TextBox Name="txbFirstName" />
<TextBox Name="txbLastName" />
<TextBox Name="txbCity" />        
<TextBox Name="txbAddress" />
<TextBox Name="txbPhone" />
  

Я хочу генерировать простые инструкции SELECT, используя входные данные текстового поля. Для этого я использую parameters и AddWithValue:

 database.SetQuery("SELECT * FROM tblCustomer WHERE FirstName = @FirstName AND LastName = @LastName AND City = @City AND Address = @Address AND Phone = @Phone;");
database.sqlCommand.Parameters.AddWithValue("@FirstName", txbFirstName.Text);
database.sqlCommand.Parameters.AddWithValue("@LastName", txbLastName.Text);
database.sqlCommand.Parameters.AddWithValue("@City", txbCity.Text);
database.sqlCommand.Parameters.AddWithValue("@Address", txbAddress.Text);
database.sqlCommand.Parameters.AddWithValue("@Phone", txbPhone.Text);
  

Теперь это работает просто отлично, но что я хочу сделать, так это то, что если ввод текстового поля пуст, обработать его с помощью NULL. Но, насколько я знаю, в запросе нельзя использовать «= NULL», вместо этого следует использовать «IS NULL», то есть я не могу написать что-то подобное:

 if (txbCity.Text == "")
    database.sqlCommand.Parameters.AddWithValue("@City", null);
else
    database.sqlCommand.Parameters.AddWithValue("@City", txbCity.Text);
  

Возможно ли передать «IS NULL» параметру с кодом? Итак, если txbCity и txbAddress были равны нулю, например:

  • Имя = John
  • Фамилия = Doe
  • City = «»
  • Адрес = «»
  • Телефон = 812-393-8144

Я бы хотел, чтобы мой запрос выглядел следующим образом:

 SELECT * FROM tblCustomer WHERE FirstName = "John" AND LastName = "Doe" AND City IS NULL AND Address IS NULL AND Phone = "812-393-8144";
  

Комментарии:

1. пробовал DBNull ?

2. Прежде всего, прекратите использовать AddWithValue . Второе — вы можете передать DBNull.Value .

3. @SeM Что я должен использовать вместо AddWithValue? Я все еще учусь и пока довольно новичок в этом.

4. @JohnDoe Например: SqlCommand. Свойство параметров или Dapper

5. @JohnDoe честно говоря, я бы сказал «пусть Dapper разбирается с этим» 🙂 имея дело с особенностями ADO.NET API — это не самое лучшее использование чьего-либо времени; Я настоятельно рекомендую позволить Dapper разобраться почти со всем этим материалом, но… Я предвзят (это инструмент доступа к данным, который мы написали для самого Stack Overflow)

Ответ №1:

В принципе: нет.

Если вы не отключили синтаксис ANSI NULL (пожалуйста, не делайте этого), вам нужен другой SQL для проверки NULL . Распространенный трюк (простой в написании, но не очень эффективный) заключается в мошенничестве с:

 WHERE (FirstName = @FirstName OR (@FirstName IS NULL AND FirstName IS NULL))
AND (LastName = @LastName OR (@LastName IS NULL AND LastName IS NULL))
-- etc x5
  

(или любой другой тест, который вы хотите выполнить для нулей) — и используйте что-то вроде:

 database.sqlCommand.Parameters.AddWithValue("@FirstName", txbFirstName.Text.DBNullIfEmpty());
database.sqlCommand.Parameters.AddWithValue("@LastName", txbLastName.Text.DBNullIfEmpty());
// etc x5
  

где DBNullIfEmpty это выглядело бы примерно так:

 internal static class MyExtensionMethods
{
    public static object DBNullIfEmpty(this string value)
    {
        if(string.IsNullOrWhiteSpace(value)) return DBNull.Value;
        return value;
    }
}
  

Комментарии:

1. Да, добавление «OR РАВНО NULL» для каждого параметра, похоже, работает правильно, спасибо!

2. @JohnDoe примечание: Я немного изменил это… это как бы зависит от того, ожидаете ли вы, что «параметр равен нулю» будет означать «не применять это условие» или «принудительно указывать, что столбец равен нулю»; (Foo = @foo OR @foo IS NULL) выполняет первое; (Foo = @foo OR (Foo IS NULL AND @foo IS NULL)) выполняет второе

Ответ №2:

Вы можете создать метод расширения для AddWithValue() и передать дополнительный третий параметр в качестве желаемого значения, когда фактическое значение равно NULL

 public static class SqlParameterCollectionExtensions {
    public static SqlParameter AddWithValue(this SqlParameterCollection target, string parameterName, object value, object nullValue) {
        if (value == null) {
            return target.AddWithValue(parameterName, nullValue);
        }
        return target.AddWithValue(parameterName, value);
    }
}
  

И позже вызвать это следующим образом

 database.sqlCommand.Parameters.AddWithValue("@City", txbCity.Text, "IS NULL");
  

Ответ №3:

Значение параметра, соответствующее NULL значению в базе данных SQL Server, равно DBNull.Value .

 Parameters.Add(“@NAME”, SqlDbType.<type>).Value = argument == null ? DBNull.Value : argument;
  

Комментарии:

1. Я не думаю, что это будет работать должным образом, потому что FirstName = NULL в sql всегда будет false, afaik (и протестировано) так и должно было быть FirstName IS NULL , поэтому весь подход не сработает. OP необходимо явно разделить случаи null.

2. Я всего лишь отвечаю на соответствующий вопрос, который он задал, имея в виду, как передать c # null в качестве параметра в SQL. Как обращаться с логикой его программы, не имеет значения.

3. Серьезно? Вы действительно думаете, что это был актуальный вопрос?

4. Ах (после вашей правки), есть еще несколько релевантных частей, например, вы не используете AddWithValue и предоставляете тип. Тем не менее, для сравнения столбцов с NULL вам нужен другой синтаксис sql, чем = или <> .