C# 空字符串参数上的System.Data.SqlTypes.SqlNullValueException

C# 空字符串参数上的System.Data.SqlTypes.SqlNullValueException,c#,sql,C#,Sql,我的问题是这一行 //query... "AND (@4 = '' OR (p.FirstName + p.LastName LIKE '%' + @4 + '%') OR (eup.FirstName + eup.LastName LIKE '%' + @4 + '%')) " + //more query... 这给了我一个数据为空异常。Param@4以“的形式出现。当我把这个改成 "AND (@4 IS NULL OR (p.FirstName + p.LastName LIKE '%'

我的问题是这一行

//query...
"AND (@4 = '' OR (p.FirstName + p.LastName LIKE '%' + @4 + '%') OR (eup.FirstName + eup.LastName LIKE '%' + @4 + '%')) " +
//more query...
这给了我一个
数据为空
异常。Param
@4
的形式出现。当我把这个改成

"AND (@4 IS NULL OR (p.FirstName + p.LastName LIKE '%' + @4 + '%') OR (eup.FirstName + eup.LastName LIKE '%' + @4 + '%')) " +
它不会返回两个表中都没有名字或姓氏的记录


我如何解决这个问题?如果param 4为空,我希望返回所有记录,而不管名称是否存在。

除非parameter
@4
包括没有空格的名字和姓氏,或者我怀疑您正在寻找与
@4
匹配的任何名字或姓氏,如果
@4
为空,则返回所有内容

AND (p.FirstName LIKE '%' ISNULL(@4,'') + '%'
    OR p.LastName LIKE '%' ISNULL(@4,'') + '%'
    OR eup.FirstName LIKE '%' ISNULL(@4,'') + '%'
    OR eup.LastName LIKE '%' ISNULL(@4,'') + '%'
    )
通过使用
ISNULL(@4',)
它将基本上把你的名字和姓氏转换成一个完整的通配符搜索,并返回所有内容,因为它前后仍然有“%”。我可能会建议将其更改为只在“%”之后添加,因为您可能会得到更适合人们查找的结果,但这取决于您


p.FirstName+p.LastName LIKE
的主要问题是
Bob Smith
将变成
BOBSMITH LIKE
。。。。虽然我想如果你坚持使用
%search string%
它仍然会返回你的结果,因为只要把
@4
切换到
ISNULL(@4',)
并去掉第一个
@4='

除非参数
@4
包括没有空格的名字和姓氏,或者我怀疑您正在寻找与
@4
匹配的任何名字或姓氏,如果
@4
为空,则返回所有内容

AND (p.FirstName LIKE '%' ISNULL(@4,'') + '%'
    OR p.LastName LIKE '%' ISNULL(@4,'') + '%'
    OR eup.FirstName LIKE '%' ISNULL(@4,'') + '%'
    OR eup.LastName LIKE '%' ISNULL(@4,'') + '%'
    )
通过使用
ISNULL(@4',)
它将基本上把你的名字和姓氏转换成一个完整的通配符搜索,并返回所有内容,因为它前后仍然有“%”。我可能会建议将其更改为只在“%”之后添加,因为您可能会得到更适合人们查找的结果,但这取决于您


p.FirstName+p.LastName LIKE
的主要问题是
Bob Smith
将变成
BOBSMITH LIKE
。。。。虽然我想如果你坚持使用
%search string%
它仍然会返回你的结果,因为只要把你的
@4
切换到
ISNULL(@4',)
并去掉第一个
@4='

我猜你的评论“两个表中都没有名字或姓氏”表示字段可为空。
如果任何一个值为null,则执行任何类似于p.FirstName+p.Lastname的操作都将给出null结果,这反过来将导致谓词结果为false。 另外,我个人不会在任何时候将这两个字段关联起来,因为您的LIKE谓词可以匹配firstname末尾和lastname开头的字符

理想情况下,您应该将字段设置为NOTNULL,然后执行此操作

"AND (@4 IS NULL 
  OR p.FirstName LIKE '%' + @4 +'%' 
  OR p.LastName LIKE '%' + @4 + '%'
  OR eup.FirstName LIKE '%' + @4 +'%'
  OR eup.LastName LIKE '%' + @4 + '%')) " +
"AND (@4 IS NULL 
  OR coalesce(p.FirstName,'') LIKE '%' + @4 +'%' 
  OR coalesce(p.LastName,'') LIKE '%' + @4 + '%'
  OR coalesce(eup.FirstName,'') LIKE '%' + @4 +'%'
  OR coalesce(eup.LastName,'') LIKE '%' + @4 + '%')) " +
如果字段必须保持为空,请执行此操作

"AND (@4 IS NULL 
  OR p.FirstName LIKE '%' + @4 +'%' 
  OR p.LastName LIKE '%' + @4 + '%'
  OR eup.FirstName LIKE '%' + @4 +'%'
  OR eup.LastName LIKE '%' + @4 + '%')) " +
"AND (@4 IS NULL 
  OR coalesce(p.FirstName,'') LIKE '%' + @4 +'%' 
  OR coalesce(p.LastName,'') LIKE '%' + @4 + '%'
  OR coalesce(eup.FirstName,'') LIKE '%' + @4 +'%'
  OR coalesce(eup.LastName,'') LIKE '%' + @4 + '%')) " +

对字段进行索引对这两种情况都没有好处,或者您的版本也没有好处,因此在大型表上,性能可能会很差。

我猜您的评论“两个表中都没有名字或姓氏”表明字段可以为空。
如果任何一个值为null,则执行任何类似于p.FirstName+p.Lastname的操作都将给出null结果,这反过来将导致谓词结果为false。 另外,我个人不会在任何时候将这两个字段关联起来,因为您的LIKE谓词可以匹配firstname末尾和lastname开头的字符

理想情况下,您应该将字段设置为NOTNULL,然后执行此操作

"AND (@4 IS NULL 
  OR p.FirstName LIKE '%' + @4 +'%' 
  OR p.LastName LIKE '%' + @4 + '%'
  OR eup.FirstName LIKE '%' + @4 +'%'
  OR eup.LastName LIKE '%' + @4 + '%')) " +
"AND (@4 IS NULL 
  OR coalesce(p.FirstName,'') LIKE '%' + @4 +'%' 
  OR coalesce(p.LastName,'') LIKE '%' + @4 + '%'
  OR coalesce(eup.FirstName,'') LIKE '%' + @4 +'%'
  OR coalesce(eup.LastName,'') LIKE '%' + @4 + '%')) " +
如果字段必须保持为空,请执行此操作

"AND (@4 IS NULL 
  OR p.FirstName LIKE '%' + @4 +'%' 
  OR p.LastName LIKE '%' + @4 + '%'
  OR eup.FirstName LIKE '%' + @4 +'%'
  OR eup.LastName LIKE '%' + @4 + '%')) " +
"AND (@4 IS NULL 
  OR coalesce(p.FirstName,'') LIKE '%' + @4 +'%' 
  OR coalesce(p.LastName,'') LIKE '%' + @4 + '%'
  OR coalesce(eup.FirstName,'') LIKE '%' + @4 +'%'
  OR coalesce(eup.LastName,'') LIKE '%' + @4 + '%')) " +

这些字段或您的版本都不会从索引字段中获益,因此在大型表中,性能可能会很差。

字段不为空。这里的问题是,广告用户存储在一个我无法在此查询中访问他们的位置,因此存在一个没有相应个人记录的用户。我知道这很愚蠢,但工作范围不涉及任何重构。字段不是空的。这里的问题是,广告用户存储在一个我无法在此查询中访问他们的位置,因此存在一个没有相应个人记录的用户。我知道这很愚蠢,但工作范围不涉及任何重构。paramater
@4
是一个连在一起的名字和姓氏。我将彻底重构这个查询,我不喜欢它的任何方面。@user8675309我刚才看到了你上面的其他评论。如果你真的在寻找一个解决方案来搜索员工数据集和你的广告记录,我敢打赌有几个问题可能会让你得到你想要的。如果不是的话,我会把它放在问题本身中,因为这是一个很好的信息,让人们在向你们提供答案时知道。我认为这里有两个独立的问题,一个是关于SQL
'
vs
null
的问题,另一个是关于广告用户的问题。我们前进的解决方案是为前进的广告用户创建人员记录,并使用脚本将现有广告用户回填到人员表中。不过非常感谢你的帮助。我最终使用了你和phils答案的混合。paramater
@4
是一个连在一起的名字和姓氏。我将彻底重构这个查询,我不喜欢它的任何方面。@user8675309我刚才看到了你上面的其他评论。如果你真的在寻找一个解决方案来搜索员工数据集和你的广告记录,我敢打赌有几个问题可能会让你得到你想要的。如果不是的话,我会把它放在问题本身中,因为这是一个很好的信息,让人们在向你们提供答案时知道。我认为这里有两个独立的问题,一个是关于SQL
'
vs
null
的问题,另一个是关于广告用户的问题。我们前进的解决方案是创造人