如何使用带有可能为null的参数的WHERE进行过滤

时间:2014-08-25 11:13:20

标签: sql tsql sql-server-ce

我使用C#写入SQL Compact Edition 3.5数据库。我有一个包含每个地址的电子邮件地址和名称的表格。

MailRecipientAddressID int primary key identity(1,1) not null,
Address nvarchar(4000),
Name nvarchar(4000)

在此表中,我希望每个地址名称组合都是唯一的。在某些情况下,AddressName可能连续NULL。在将新行插入此表之前,我使用SELECT查询来检查是否存在与我要插入的行匹配的现有行。使用此查询时

SELECT MailRecipientAddressID FROM MailRecipientAddress WHERE Address = @Address AND Name = @Name

我不会在一列中找到包含NULL值的现有行(请参阅here)。

现在我得到了这个查询,它可以解决我的问题

SELECT MailRecipientAddressID FROM MailRecipientAddress WHERE ISNULL(Address, '') = ISNULL(@Address, '') AND ISNULL(Name, '') = ISNULL(@Name, '')

但即使在我的情况下没有问题NULL和空字符串值被平等处理,我也不喜欢这个解决方案。我认为这是一种hackish。有没有更好的方法

  • 对SELECT语句应用过滤器,其参数可以包含NULL
  • 适用于SQL CE


修改

我不明白为什么,但我的查询适用于SQL Management Studio,但它不在我的应用程序中(参见here)。要纠正我自己的方法,我需要使用COALESCE

我不喜欢用空字符串替换NULL值的选项,因为我认为在我没有价值的地方设置值或者我对这个设计问题错了?

3 个答案:

答案 0 :(得分:1)

最佳解决方案是对表格的约束,阻止重复进入表格。您可以使用唯一索引放入一个:

create unique index idx_MailRecipientAddress_address_name on MailRecipientAddress(Address, Name);

这将在insert上生成错误,然后您需要捕获该错误。

但是,这只是一个部分解决方案,因为NULL值不算重复。您可以通过在字段中不允许NULL值来解决您的整体问题。相反,使用空字符串表示没有数据。注意:我通常不建议这样做。在SQL中,NULL表示“未知”,根据语言的定义,两个“未知”值不相等。但是,你似乎希望它们是平等的。

至于SQL,你的可以,但它等于NULL和空字符串。明确的检查更准确:

WHERE (Address = @Address or Address is null and @Address is null) and
      (Name = @Name or Name is null and @Name is null)

答案 1 :(得分:0)

@George

如果参数值为Null且列值不为null,则"(Address = @Address或Address为NULL)返回false"

如果参数值为Null且列值为null,则"(Address = @Address或Address为NULL)返回true"

如果参数值为非空且列值为空,则"(地址= @Address或地址为NULL)返回true"

如果参数值为非空且列值为非空且如果匹配,那么"(地址= @Address或地址为NULL)返回true,否则返回false"

答案 2 :(得分:-1)

SELECT MailRecipientAddressID FROM MailRecipientAddress WHERE (Address = @Address or Address is NULL) AND (Name = @Name or Name is NULL)