0

我已经开始创建一个存储过程,它将根据传递的参数搜索我的数据库表。到目前为止,我已经听说过kitchen sink parameter sniffing. 有几篇文章有助于理解这个问题,但我仍然不是 100% 有一个好的解决方案。我在系统中有几个屏幕将在我的数据库中搜索不同的表。它们都具有用户将选择和搜索的三个不同标准。第一个标准是Status可以是ActiveInactiveAll。接下来是Filter By,这可以根据表和列数为用户提供不同的选项。通常,用户可以选择按NameCodeNumberDOBEmailUserNameShow All. 每个搜索屏幕至少有 3 个过滤器,其中一个是Show All. 我创建了一个存储过程,用户可以在其中搜索StatusFilter By NameCodeShow All。我遇到的一个问题是Status过滤器。似乎 SQL 将检查 where 子句中的所有选项,所以如果我通过参数1SP 返回所有活动记录,如果我通过0则只有非活动记录。问题是如果我通过2SP 应该返回所有记录(活动和非活动),但我只看到活动记录。这是一个例子:

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)
        );

除了状态过滤器的问题,我想知道参数嗅探是否还有其他问题?我发现了一篇关于防止嗅探的博客,其中一种方法是声明局部变量。如果有人对状态过滤器有建议或解决方案,请告诉我。

4

1 回答 1

1

关于您的Status问题,我认为问题在于您的BIT参数的行为与您期望的不同。这是一个快速测试来演示:

DECLARE @bit BIT;

SET @bit = 2

SELECT @bit AS [2=What?];

--Results
+---------+
| 2=What? |
+---------+
|       1 |
+---------+

来自我们在微软的朋友:

转换为位会将任何非零值提升为 1。

当您将参数作为 传递时,引擎会从to2进行隐式转换,并且您的非零值变为.INTEGERBIT1

您可能希望更改该参数的数据类型,然后在您的过程中使用一些条件逻辑来处理您希望处理的各种可能值。

关于参数嗅探的问题,1)阅读 Sean 在评论中建议的文章,但是 2)如果您将其保留WITH RECOMPILE在您的程序中,则不会发生参数嗅探。

问题(但仍然阅读文章)是 SQL Server 使用您通过 proc 发送的第一组参数来存储执行计划,但后续参数需要大不相同的计划。添加WITH RECOMPILE会在每次迭代中强制执行一个新的执行计划,这会产生一些开销,但很可能正是您想要在您的情况下执行的操作。

总结一下,SQL Server 2008 于 2014 年结束主流支持,扩展支持于 2019年 7 月 9 日结束。升级可能是个好主意。

于 2018-08-10T16:58:27.420 回答