【问题标题】:Pass "IS NULL" via parameter通过参数传递“IS NULL”
【发布时间】:2023-04-05 17:33:01
【问题描述】:

我有 5 个文本框:

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

我想使用文本框输入生成简单的 SELECT 语句。为此,我使用参数和 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 为空,例如:

  • 名字 = 约翰
  • 姓氏 = Doe
  • 城市 = ""
  • 地址 = ""
  • 电话 = 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";

【问题讨论】:

  • 试过DbNull?
  • 首先,stop using AddWithValue。第二——你可以通过DBNull.Value。
  • @SeM 我应该使用什么来代替 AddWithValue?我现在还在学习,而且很菜鸟。
  • @JohnDoe 例如:SqlCommand.Parameters Property 或 Dapper
  • @JohnDoe 坦率地说,我会说“让 Dapper 处理它”:) 处理 ADO.NET API 的特殊性并不能很好地利用任何人的时间;我强烈建议让 Dapper 处理几乎所有这些东西,但是......我有偏见(它是我们为 Stack Overflow 本身编写的数据访问工具)

标签: c# wpf sqlite


【解决方案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;
    }
}

【讨论】:

  • 是的,为每个参数添加“OR IS NULL”似乎可以正常工作,谢谢!
  • @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】:

    SQL Server数据库中NULL值对应的参数值为DBNull.Value。

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

    【讨论】:

    • 我认为这不会正常工作,因为FirstName = NULL 在 sql 中总是错误的,afaik(并经过测试)它必须是FirstName IS NULL,所以整个方法都行不通. OP 需要明确分隔空案例。
    • 我只是在回答他提出的相关问题,即如何在 SQL 中将 c# null 作为参数传递。如何处理他的程序的逻辑无关紧要。
    • 认真的吗?你真的认为这是相关的问题吗?
    • 啊(在您编辑之后),还有一些更相关的部分,例如您不使用 AddWithValue 并提供类型。尽管如此,要将列与NULL 进行比较,您需要与= 或&lt;&gt; 不同的sql 语法。
    猜你喜欢
    • 2022-06-11
    • 1970-01-01
    • 1970-01-01
    • 2022-01-25
    • 2014-05-22
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    相关资源
    最近更新 更多