繁体   English   中英

防止在存储过程中嗅探参数SQL Server 2008?

[英]Prevent parameter sniffing in stored procedures SQL Server 2008?

我已经开始创建一个存储过程,该过程将根据传递的参数搜索数据库表。 到目前为止,我已经听说过kitchen sink parameter sniffing潜在问题。 有几篇文章可以帮助您理解该问题,但我仍然不是100%拥有一个好的解决方案。 我在系统中有几个屏幕可以搜索数据库中的不同表。 它们都有三个不同的条件供用户选择和搜索。 第一个条件是Status Active ,“ Inactive或“ All 接下来是Filter By ,这可以根据表和列数向用户提供不同的选项。 通常,用户可以选择按NameCodeNumberDOBEmailUserNameShow All进行过滤。 每个搜索屏幕将至少具有3个过滤器,其中一个将是“ Show All 我创建了一个存储过程,用户可以在其中搜索“ Status并按NameCodeShow All Filter By Status一个问题是Status过滤器。 似乎SQL将检查where子句中的所有选项,因此如果我传递参数1则如果我传递0 SP将返回所有活动记录,然后仅返回非活动记录。 问题是如果我通过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)
        );

除了状态过滤器的问题外,我想知道参数嗅探是否还有其他问题? 我找到了一个博客,该博客谈论防止嗅探,并且做到这一点的一种方法是声明局部变量。 如果有人对状态过滤器有建议或解决方案,请告诉我。

在您的Status问题上,我认为问题在于您的BIT参数无法正常运行。 这是一个快速测试以演示:

DECLARE @bit BIT;

SET @bit = 2

SELECT @bit AS [2=What?];

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

来自Microsoft的朋友:

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

当您将参数传递为2 ,引擎将进行从INTEGERBIT的隐式转换,并且您的非零值将变为1

您可能需要更改该参数上的数据类型,然后在过程中使用一些条件逻辑来处理各种可能的值(如希望对其进行处理)。

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

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

作为总结 ,SQL Server 2008在2014年终止了主流支持,而扩展支持在7/9/2019结束 升级可能是个好主意。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM