Sql server 存储过程中的条件提示

Sql server 存储过程中的条件提示,sql-server,Sql Server,除了在存储过程中复制查询之外,是否有任何方法可以基于存储过程参数指定提示?例如,对于参数@waitForLock,如果它设置为0,我想使用readpass提示,否则等待/阻止,直到另一个事务完成。一般来说,我喜欢选项RECOMPILE建议,尽管这意味着它每次都会重新编译,即使统计数据或您的参数没有更改。这通常是为了阻止参数嗅探,对于您希望避免或不希望避免使用锁的情况没有帮助 一个想法是使用动态SQL(这也可能是有益的,这取决于您的“针对特定工作负载进行优化”设置以及使用一个或另一个参数运行的频率

除了在存储过程中复制查询之外,是否有任何方法可以基于存储过程参数指定提示?例如,对于参数
@waitForLock
,如果它设置为0,我想使用
readpass
提示,否则等待/阻止,直到另一个事务完成。

一般来说,我喜欢
选项RECOMPILE
建议,尽管这意味着它每次都会重新编译,即使统计数据或您的参数没有更改。这通常是为了阻止参数嗅探,对于您希望避免或不希望避免使用锁的情况没有帮助

一个想法是使用动态SQL(这也可能是有益的,这取决于您的“针对特定工作负载进行优化”设置以及使用一个或另一个参数运行的频率)

创建过程dbo.where
@waitForLock位=1
作为
开始
不计数;
声明@sql NVARCHAR(最大值);
SET@sql='从dbo.某处选择某物';
如果@waitForLock=0
将@sql=@sql+'设置为(readpass)';
SET@sql='WHERE…';
EXEC sp_executesql@sql;
结束
去

我从未见过这样的事情。我想你需要一个带有两个查询的IF/ELSE(一个带锁,一个不带锁)@Joe:是的,我在考虑这两个查询,因为显然一个
CASE
语句不起作用。如果这是另一种类型的提示(例如,
NOLOCK
),可能您可以执行条件隔离级别:
如果@NOLOCK=1,则设置事务隔离读取未提交,否则设置事务隔离读取已提交
。。。然后进行查询。没错,我没有考虑过动态SQL,但那会起作用。我最终意识到,在我的具体实现中,等待另一个事务(不执行
readpass
)真的没有帮助。第一个事务更新一个列值,这意味着我无论如何都不会得到结果,所以我最好尽早退出。唯一的例外是如果第一个事务回滚,这只会在出错时发生,而且不太可能。
CREATE PROCEDURE dbo.whatever
    @waitForLock BIT = 1
AS
BEGIN
   SET NOCOUNT ON;

   DECLARE @sql NVARCHAR(MAX);

   SET @sql = 'SELECT something FROM dbo.somewhere';

   IF @waitForLock = 0
      SET @sql = @sql + ' WITH (READPAST)';

   SET @sql = ' WHERE <some condition> ...';

   EXEC sp_executesql @sql;
END
GO