我喜欢通过将一堆输入参数都默认为NULL来减少我拥有的存储过程的数量,然后使用Equality或NULL测试在WHERE中包含相同的参数。
这与查询性能有多低效 - 为1个特定任务编写存储过程?例如仅按UserId选择,按用户名/密码选择,按FirstName / LastName选择...
示例:
CREATE PROC dbo.up_Select_User
@UserId int = NULL
, @Username varchar(255) = NULL
, @Password varchar(255) = NULL
, @FirstName varchar(50) = NULL
, @LastName varchar(50) = NULL
, @IsActive bit = NULL
SELECT UserId, Username, FirstName, LastName, EmailAddress
FROM dbo.[User]
WHERE (UserId = @UserId OR @UserId IS NULL)
AND (Username = @Username OR @Username IS NULL)
AND (Password = @Password OR @Password IS NULL)
AND (FirstName = @FirstName OR @FirstName IS NULL)
AND (LastName = @LastName OR @LastName IS NULL)
AND (IsActive = @IsActive OR @IsActive IS NULL)
一些额外的信息 - 可能不相关......我使用实体框架4根据查询结果使用普通实体和复杂类型的混合映射到存储过程。
答案 0 :(得分:7)
这是低效的,因为它使用OR而优化器将默认为扫描。
如果你有几千行,那就可以了。
有时候,这个模式效果更好,因为ISNULL可以变得微不足道
SELECT UserId, Username, FirstName, LastName, EmailAddress
FROM dbo.[User]
WHERE
UserId = ISNULL(@UserId, UserId) AND
Username = ISNULL(@Username , Username) AND
Password = ISNULL(@Password , Password ) ...
答案 1 :(得分:1)
我们使用这种方式过滤
AND (CASE @UserId WHEN NULL THEN @UserId ELSE UserId END) = @UserId
使用该解决方案,SqlServer上的大数据没有性能问题
某些应用程序视图(如报表概述页面)具有20多个过滤器设置,并且与CASE WHEN
构造一起使用效果很好。
编辑: 必须设置这些SET选项
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS OFF
答案 2 :(得分:0)
@gbn: 小心,带有ISNULL的版本并不完全相同。 例如。 如果参数@FirstName为NULL
... AND (FirstName = @FirstName OR @FirstName IS NULL)
不会处理FirstName值;结果包括FirstName为NULL的记录
,而
... AND FirstName = ISNULL(@FirstName, FirstName)
结果不包含FirstName为NULL的记录