我已经开始创建一个存储过程,它将根据传递的参数搜索我的数据库表。到目前为止,我已经听说过kitchen sink parameter sniffing
. 有几篇文章有助于理解这个问题,但我仍然不是 100% 有一个好的解决方案。我在系统中有几个屏幕将在我的数据库中搜索不同的表。它们都具有用户将选择和搜索的三个不同标准。第一个标准是Status
可以是Active
,Inactive
或All
。接下来是Filter By
,这可以根据表和列数为用户提供不同的选项。通常,用户可以选择按Name
、Code
、Number
、DOB
、Email
、UserName
或Show All
. 每个搜索屏幕至少有 3 个过滤器,其中一个是Show All
. 我创建了一个存储过程,用户可以在其中搜索Status
和Filter By
Name
,Code
或Show All
。我遇到的一个问题是Status
过滤器。似乎 SQL 将检查 where 子句中的所有选项,所以如果我通过参数1
SP 返回所有活动记录,如果我通过0
则只有非活动记录。问题是如果我通过2
SP 应该返回所有记录(活动和非活动),但我只看到活动记录。这是一个例子:
USE [TestDB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROC [dbo].[Search_Master]
@Status BIT = NULL,
@FilterBy INT = NULL,
@Name VARCHAR(50) = NULL,
@Code CHAR(2) = NULL
WITH RECOMPILE
AS
DECLARE @MasterStatus INT;
DECLARE @MasterFilter INT;
DECLARE @MasterName VARCHAR(50);
DECLARE @MasterCode CHAR(2);
SET @MasterStatus = @Status;
SET @MasterFilter = @FilterBy;
SET @MasterName = @Name;
SET @MasterCode = @Code;
SELECT RecID, Status, Code, Name
FROM Master
WHERE
(
(@MasterFilter = 1 AND Name LIKE '%'+@MasterName+'%')
OR
(@MasterFilter = 2 AND Code = @MasterCode)
OR
(@MasterFilter = 3 AND @MasterName IS NULL AND @MasterCode IS NULL)
)
AND
(
(@MasterStatus != 2 AND MasterStatus = @Status)
OR
(@MasterStatus = 2 AND 1=1)
);
除了状态过滤器的问题,我想知道参数嗅探是否还有其他问题?我发现了一篇关于防止嗅探的博客,其中一种方法是声明局部变量。如果有人对状态过滤器有建议或解决方案,请告诉我。