Sql 存储过程中可选参数的最佳解决方案

Sql 存储过程中可选参数的最佳解决方案,sql,sql-server,dynamic-sql,Sql,Sql Server,Dynamic Sql,考虑以下采用一些参数的示例过程 Create Procedure CustomerSearch( @Name nVarChar(100) = Null, @Phone nVarChar(100) = Null, @Address nVarChar(100) = Null, ) As Select * From dbo.CustomerView Where (@Name is Null or Name =

考虑以下采用一些参数的示例过程

Create Procedure CustomerSearch(
@Name       nVarChar(100) = Null,
@Phone      nVarChar(100) = Null,
@Address    nVarChar(100) = Null,
)
As

Select  *
        From    dbo.CustomerView
        Where   (@Name      is Null or Name     =   @Name)  And
                (@Phone     is Null or Phone    =   @Phone) And
                (@Address   is Null or Address  =   @Address)
因为参数的值可能为null,所以我找到了两种解决方案来处理它

  • 像这样使用或继续: (@Name为Null或Name=@Name)
  • 使用动态sql并添加条件来查询参数值是否不为null
  • CustomerView视图中存在多个表联接,该表具有大量数据,性能非常重要。解决方案1有开销(执行计划)。由于某些原因,我不能使用动态sql。有更好的方法来构建此查询吗


    当我使用条件@Name为Null或Name=@Name)而不是Name=@Name和view执行计划时,索引查找成本会增加。

    您上面发布的代码完全可以接受。如果性能有问题,请确保姓名、电话和地址列上有索引。

    您上面发布的代码完全可以接受。如果性能有问题,请确保姓名、电话和地址列上有索引。

    您的代码工作正常,对于您的情况,我会将参数包装在NULLIF(@Parameter')中,以防止比较空格

    这里还有另一种编写查询的方法。如果参数为空或null,它会将列与自身进行比较,这始终是真的

    Name = COALESCE(NULLIF(@Name,''),Name)
    

    您的代码运行良好,对于您的情况,我会将参数包装在NULLIF(@Parameter')中,以防止比较空格

    这里还有另一种编写查询的方法。如果参数为空或null,它会将列与自身进行比较,这始终是真的

    Name = COALESCE(NULLIF(@Name,''),Name)
    

    您可能还需要考虑将
    选项(重新编译)
    添加到存储过程的末尾

    每当存储过程第一次在SQL Server中运行时,都会对其进行优化,并在SQL Server内存中编译和缓存查询计划

    从:

    重新编译
    指示SQL Server数据库引擎在执行查询后放弃为查询生成的计划,强制查询优化器在下次执行同一查询时重新编译查询计划。在不指定重新编译的情况下,数据库引擎缓存查询计划并重用它们。编译查询计划时,重新编译查询提示使用查询中任何局部变量的当前值,如果查询在存储过程中,则使用传递给任何参数的当前值。
    当只需要重新编译存储过程中的查询子集而不是整个存储过程时,重新编译是创建使用WITH RECOMPILE子句的存储过程的有用替代方法。有关详细信息,请参见重新编译存储过程。在创建计划指南时,重新编译也很有用


    您可能还想查看将
    选项(重新编译)
    添加到存储过程的末尾

    每当存储过程第一次在SQL Server中运行时,都会对其进行优化,并在SQL Server内存中编译和缓存查询计划

    从:

    重新编译
    指示SQL Server数据库引擎在执行查询后放弃为查询生成的计划,强制查询优化器在下次执行同一查询时重新编译查询计划。在不指定重新编译的情况下,数据库引擎缓存查询计划并重用它们。编译查询计划时,重新编译查询提示使用查询中任何局部变量的当前值,如果查询在存储过程中,则使用传递给任何参数的当前值。
    当只需要重新编译存储过程中的查询子集而不是整个存储过程时,重新编译是创建使用WITH RECOMPILE子句的存储过程的有用替代方法。有关详细信息,请参见重新编译存储过程。在创建计划指南时,重新编译也很有用


    您可能会发现此资源很有用:。您可能会发现此资源很有用:。我已为此列创建了索引,这不是我的问题。当我运行查询时,它会花费太多的时间,当我查看执行计划时,它(检查null参数)会使用进程而不是使用name=@name条件。您能提供创建的索引吗?我在这列上创建了索引,这不是我的问题。当我运行查询时,它会花费太多的时间,当我查看执行计划时,它(检查null参数)会使用进程而不是使用name=@name条件。您能提供创建的索引吗?确定。注意,我的问题是条件(@Name为Null或Name=@Name)的索引查找成本增加,而不是Name=@Name.Ok。请注意,我的问题是条件(@Name为Null或Name=@Name)的索引查找成本增加,而不是Name=@Name。