Sql 如果表列具有空值,则无法检索

Sql 如果表列具有空值,则无法检索,sql,sql-server-2008,Sql,Sql Server 2008,我有一个存储过程来查找客户,它工作正常。如果表中Customer\u City\u Name为空,则我无法检索该行。SP出现故障。如何做到这一点 即使客户\城市\名称或客户\国家\代码为空,我也必须得到结果 SP代码: CREATE PROCEDURE findCustomer @customerNumber NVARCHAR(100), @customerNamePattern NVARCHAR(35), @customerCityNamePattern NVARCHAR(35)

我有一个存储过程来查找客户,它工作正常。如果表中Customer\u City\u Name为空,则我无法检索该行。SP出现故障。如何做到这一点 即使客户\城市\名称或客户\国家\代码为空,我也必须得到结果

SP代码:

CREATE PROCEDURE  findCustomer
  @customerNumber NVARCHAR(100),
  @customerNamePattern NVARCHAR(35),
  @customerCityNamePattern NVARCHAR(35),
  @customerCountryCode NVARCHAR(5)
AS

BEGIN
DECLARE @SQL NVARCHAR(4000)
SET @SQL =
'
SELECT
c.Customer_Number,
c.Customer_Name,
c.Postal_Address_Identifier,
c.Customer_Street_Or_Road_Name,
c.Customer_City_Name,
c.Customer_Territory_Code,
c.Customer_Postal_Code,
c.Customer_Country_Code,
c.Telephone_Number,
c.Mobile_Telephone_Number,
c.Fax_Number,
c.Email_Address 
FROM Customer c  
WHERE c.Customer_Number LIKE ' +
        CASE WHEN @customerNumber IS NOT NULL
             THEN '''' + @customerNumber + ''''
             ELSE 'c.Customer_Number'
        END + '
AND c.Customer_Name LIKE ' +
        CASE WHEN @customerNamePattern IS NOT NULL
            THEN '''' + @customerNamePattern + ''''
            ELSE 'c.Customer_Name'
        END + '
AND c.Customer_City_Name LIKE ' +
        CASE WHEN @customerCityNamePattern IS NOT NULL
            THEN '''' +@customerCityNamePattern + ''''
            ELSE 'c.Customer_City_Name'
        END + '
AND c.Customer_Country_Code LIKE ' +
        CASE WHEN @customerCountryCode IS NOT NULL
            THEN '''' +@customerCountryCode + ''''
            ELSE 'c.Customer_Country_Code'
        END

EXEC sp_executesql @SQL

@user2218371您应该重新考虑替代方案,而不是动态SQL。无论如何,这是另一种代码

CREATE PROCEDURE  findCustomer
  @customerNumber NVARCHAR(100),
  @customerNamePattern NVARCHAR(35),
  @customerCityNamePattern NVARCHAR(35),
  @customerCountryCode NVARCHAR(5)
AS

BEGIN
DECLARE @SQL NVARCHAR(4000)
SET @SQL =
'
SELECT
c.Customer_Number,
c.Customer_Name,
c.Postal_Address_Identifier,
c.Customer_Street_Or_Road_Name,
c.Customer_City_Name,
c.Customer_Territory_Code,
c.Customer_Postal_Code,
c.Customer_Country_Code,
c.Telephone_Number,
c.Mobile_Telephone_Number,
c.Fax_Number,
c.Email_Address 
FROM Customer c  
WHERE ' + 
    CASE WHEN  @customerNumber IS NOT NULL 
        THEN ' c.Customer_Number LIKE ''' + @customerNumber + '''' + 
            CASE WHEN  @customerNamePattern IS NOT NULL THEN ' AND ' ELSE '' END
        ELSE '' 
    END  +
    CASE WHEN   @customerNamePattern IS NOT NULL 
        THEN ' c.Customer_Name LIKE ''' +  @customerNamePattern + '''' + 
            CASE WHEN  @customerCityNamePattern IS NOT NULL THEN ' AND ' ELSE '' END
        ELSE '' 
    END  + 
    CASE WHEN   @customerCityNamePattern IS NOT NULL 
        THEN ' c.Customer_City_Name LIKE ''' +  @customerCityNamePattern + '''' + 
            CASE WHEN  +@customerCountryCode IS NOT NULL THEN ' AND ' ELSE '' END
        ELSE '' 
    END  + 
    CASE WHEN    @customerCountryCode IS NOT NULL 
        THEN ' c.Customer_Country_Code LIKE ''' +  @customerCountryCode + ''''
        ELSE '' 
    END     

EXEC sp_executesql @SQL
当其中一个字段为空时,WHERE子句如下所示:

WHERE c.Customer_Number LIKE c.Customer_Number
这显然是故意的,因为这是案件陈述的一部分

但是,对于一对空值,LIKE不会返回true。NULL与NULL不同。这是NULL的典型行为做同样的事情

请参阅此非常简单的SQL FIDLE进行演示:

假设我读得正确,当过程参数为NULL时,您只需忽略列的值。在这种情况下,当参数为NULL时,您需要调整查询以完全省略子句,或者放置一些始终为true的表达式

如果您坚持使用不应该使用的动态SQL构建函数,请在案例语句中尝试以下方法:

WHERE ' +
CASE WHEN @customerNumber IS NOT NULL
     THEN 'c.Customer_Number LIKE ''' + @customerNumber + ''''
     ELSE '0=0'
END + '
空值不能与任何其他值进行比较,这意味着您不能得到真值或假值。 为了解决这个问题,我使用了ISNULL内置函数,该函数检查值是否为null,以及它是否返回默认值

您应该将此函数应用于空值为选项的每一列


兄弟,所以您的查询主要是执行选择功能来搜索现有的客户信息

尝试修改您的where条件,如下示例所示

Select ....
From .....
WHERE (@Customer_Number is null or c.Customer_Number like @Customer_Number + '%')
AND (@customerNamePattern is null or c.Customer_Name  like @customerNamePattern + '%' )
AND (@customerCityNamePatternis null or c.Customer_City_Name   like @customerCityNamePattern+ '%' )
AND (@customerCountryCode is null or c.c.Customer_Country_Code like @customerCountryCode + '%' )

我通过这样做解决了这个问题

还有ISnullc.Customer\u City\u Name,比如'+ @customerCityNamePattern不为NULL时的情况 然后+@customerCityNamePattern+ ELSE'为空,c.Customer\u City\u Name,' 结束+' 还有Isnullc.Customer\u Country\u代码,比如'+ @customerCountryCode不为空时的情况 然后+@customerCountryCode+ ELSE'isnullc.Customer\u Country\u Code,' 结束

感谢asafrob,我接受了你的方法。 2.多亏了德维奥,我从他那里得到了这个主意 3.感谢jpmc26->我喜欢你的答案。
最后感谢所有回答我问题的人

天哪!请重新格式化并清理你的帖子-这是一个巨大的混乱!请在文本编辑器中突出显示代码行,并单击编辑器工具栏上的“代码示例”按钮{},以很好地格式化和语法突出显示它!您有一个生成动态SQL并执行它的存储过程。不能改用参数化查询吗?由于这是一个客户搜索,我在这段代码中添加了分页,所以我添加了动态SQL。最简单的修复方法是将表的所有四列更新为非空?抱歉?所以您现在的问题是使用NOTNULL columns值更新表?这是blur,你能更新你的问题吗^___^在我的回答中,我没有足够清楚地说明这一点,但是您的动态SQL非常容易受到SQL注入攻击。考虑参数化查询或至少某种类型的输入验证。这是唯一的方法。我能产生预期的结果
Select ....
From .....
WHERE (@Customer_Number is null or c.Customer_Number like @Customer_Number + '%')
AND (@customerNamePattern is null or c.Customer_Name  like @customerNamePattern + '%' )
AND (@customerCityNamePatternis null or c.Customer_City_Name   like @customerCityNamePattern+ '%' )
AND (@customerCountryCode is null or c.c.Customer_Country_Code like @customerCountryCode + '%' )