我使用C#写入SQL Compact Edition 3.5数据库。我有一个包含每个地址的电子邮件地址和名称的表格。
MailRecipientAddressID int primary key identity(1,1) not null,
Address nvarchar(4000),
Name nvarchar(4000)
在此表中,我希望每个地址名称组合都是唯一的。在某些情况下,Address
或Name
可能连续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。有没有更好的方法
的修改
我不明白为什么,但我的查询适用于SQL Management Studio,但它不在我的应用程序中(参见here)。要纠正我自己的方法,我需要使用COALESCE。
我不喜欢用空字符串替换NULL
值的选项,因为我认为在我没有价值的地方设置值或者我对这个设计问题错了?
答案 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)