tsql - 如何在 T-SQL 存储过程中使用可选参数?

标签 tsql select filter optional-parameters

我正在创建一个存储过程来对表进行搜索。我有许多不同的搜索字段,所有这些都是可选的。有没有办法创建一个存储过程来处理这个问题?假设我有一个包含四个字段的表:ID、FirstName、LastName 和 Title。我可以做这样的事情:

CREATE PROCEDURE spDoSearch
    @FirstName varchar(25) = null,
    @LastName varchar(25) = null,
    @Title varchar(25) = null
AS
    BEGIN
        SELECT ID, FirstName, LastName, Title
        FROM tblUsers
        WHERE
            FirstName = ISNULL(@FirstName, FirstName) AND
            LastName = ISNULL(@LastName, LastName) AND
            Title = ISNULL(@Title, Title)
    END

这种作品。但是,它会忽略 FirstName、LastName 或 Title 为 NULL 的记录。如果搜索参数中未指定标题,我想包含标题为 NULL 的记录 - 名字和姓氏相同。我知道我可以使用动态 SQL 来做到这一点,但我想避免这种情况。

最佳答案

根据给定参数动态改变搜索是一个复杂的主题,并且以一种不同的方式进行,即使只有非常微小的差异,也会产生巨大的性能影响。关键是使用索引,忽略紧凑的代码,忽略重复代码的担忧,必须制定好的查询执行计划(使用索引)。

阅读本文并考虑所有方法。您的最佳方法将取决于您的参数、数据、架构和实际使用情况:

Dynamic Search Conditions in T-SQL by by Erland Sommarskog

The Curse and Blessings of Dynamic SQL by Erland Sommarskog

如果您有正确的 SQL Server 2008 版本(SQL 2008 SP1 CU5 (10.0.2746) 及更高版本),您可以使用这个小技巧来实际使用索引:

选项(重新编译)添加到您的查询中,see Erland's article ,并且 SQL Server 将在基于局部变量的运行时值创建查询计划之前从 (@LastName IS NULL OR LastName= @LastName) 解析 OR ,并且可以使用索引。

这适用于任何 SQL Server 版本(返回正确的结果),但仅当您使用 SQL 2008 SP1 CU5 (10.0.2746) 及更高版本时才包含选项(RECOMPILE)。 OPTION(RECOMPILE) 将重新编译您的查询,只有列出的版本才会根据局部变量的当前运行时值重新编译它,这将为您提供最佳性能。如果不在该版本的 SQL Server 2008 上,则将该行保留为关闭。

CREATE PROCEDURE spDoSearch
    @FirstName varchar(25) = null,
    @LastName varchar(25) = null,
    @Title varchar(25) = null
AS
    BEGIN
        SELECT ID, FirstName, LastName, Title
        FROM tblUsers
        WHERE
                (@FirstName IS NULL OR (FirstName = @FirstName))
            AND (@LastName  IS NULL OR (LastName  = @LastName ))
            AND (@Title     IS NULL OR (Title     = @Title    ))
        OPTION (RECOMPILE) ---<<<<use if on for SQL 2008 SP1 CU5 (10.0.2746) and later
    END

关于tsql - 如何在 T-SQL 存储过程中使用可选参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3415582/

相关文章:

sql-server - 如何从字符串 id 中选择 id 所在的数据?

SQL Server 仅使用最新值选择不同的行

jQuery <选择> : how to get $(this. ID) :first?

java - 将过滤选项添加到 JTable 的列标题

java - 如何反射(reflect)过滤列表中的更改

sql-server - 如何在 temptable 中捕获 DBCC 语句的输出

tsql - 条件 where 子句 T-SQL

mysql - 从子选择返回行

C# web 浏览器选择列表项单击

PHP如何过滤 'in a correct way'所有$_POST变量