用于处理可选WHERE子句筛选器的更简洁的SQL查询
请参见下面的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的观察,我已经对您的查
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语句。