用于处理可选WHERE子句筛选器的更简洁的SQL查询

用于处理可选WHERE子句筛选器的更简洁的SQL查询,sql,sql-server-2005,tsql,syntax,Sql,Sql Server 2005,Tsql,Syntax,请参见下面的SQL语句: 有没有更好的方法来消除案例陈述 select * from Customer where FirstName like ISNULL('ja','') + '%' AND [EmailId] LIKE ISNULL('jaisonshereen@gmail.com1','') + CASE when 'jaisonshereen@gmail.com1' = '' then '%' else '' end 根据@Thor84no的观察,我已经对您的查

请参见下面的SQL语句:

有没有更好的方法来消除案例陈述

select * from Customer 
where FirstName like ISNULL('ja','') + '%'  
AND [EmailId] LIKE ISNULL('jaisonshereen@gmail.com1','') 
    + CASE when 'jaisonshereen@gmail.com1' =  '' then '%' else ''  end

根据@Thor84no的观察,我已经对您的查询进行了参数化,假设它是代码生成的,并假设满足以下要求:

@Firstname和@Email都是可选的 如果@Firstname不是null或空白,请始终使用%作为后缀并执行类似操作,否则,请应用类似“%”的伪筛选器 如果@Email不是null或空白,则执行类似@Email的精确搜索,否则应用类似“%”的伪筛选器 所以它的参数化如下:

DECLARE @FirstName NVARCHAR(100)
DECLARE @EmailId NVARCHAR(100)
SET @FirstName = 'ja'
SET @EmailId = 'jaisonshereen@gmail.com1'

select * from Customer 
where FirstName like ISNULL(@FirstName,'') + N'%'  
AND [EmailId] LIKE ISNULL(@EmailId, N'') 
    + CASE when @EmailId =  N'' then N'%' else N''  end
我相信有一种情况是你无法处理的,即如果@Email为空,你需要将最后一行改为空

+ CASE when IsNull(@EmailId, '') =  N'' then N'%' else N''  end
代码的查询计划非常好-它将始终位于FirstName(如“..%”和EMailId(如“..”)或EMailId(如“%”)的位置-这可能就是代码生成器执行此操作的原因

尽管出于可读性考虑,可能会执行以下操作,“或”会影响查询计划,通常会导致表/索引扫描

select * from Customer 
WHERE 
(ISNULL(@FirstName, N'') = N'' OR FirstName LIKE @FirstName + N'%')
AND (ISNULL(@EmailId, N'') = N'' OR [EmailId] = @EmailId) -- Assuming ANSI Nulls are ON
所以,尽管你所得到的看起来很混乱,但实际上是非常理想的

出于兴趣,动态SQL,例如由LINQ2SQL、EF等ORM生成的,在大量参数是可选的情况下,通常比存储过程具有优势。 通过使用参数化SQL,仍然可以缓存查询计划,并且可以保护查询免受SQL注入攻击。比较

DECLARE @FirstName NVARCHAR(100)
DECLARE @EmailId NVARCHAR(100)
SET @FirstName = 'ja'
SET @EmailId = 'jaisonshereen@gmail.com1'

DECLARE @SQL NVARCHAR(MAX)
SET @SQL = N'SELECT * FROM Customer '

IF ISNULL(@FirstName,'') <> N'' OR ISNULL(@EmailId, N'') <> N''
    SET @SQL = @SQL + N'WHERE ' -- Need to handle the case where neither param provided

IF ISNULL(@FirstName, N'') <> N''
    SET @SQL = @SQL + N' FirstName LIKE @FirstName + ''%'''

IF ISNULL(@FirstName,'') <> N'' AND ISNULL(@EmailId, N'') <> N''
    SET @SQL = @SQL + N' AND'

IF ISNULL(@EmailId,'') <> N''
    SET @SQL = @SQL + N' EmailId = @EmailId' -- Exact match

exec sp_ExecuteSQL @SQL, N'@FirstName NVARCHAR(100), @EmailId NVARCHAR(100)', @FirstName=@FirstName, @EmailId=@EmailId

你为什么要这样合并非空常量?你是说IsNullCustomer.Email吗?看起来你还试图在SQL中做更多不必要的事情。我想你是在执行它生成的代码吧?如果是这样的话,最好在那里执行isnull/case语句。