sp_executesql:可以参数化的内容

use*_*098 4 sql-server dynamic-sql parameter

是否有发布的明确列表显示在调用 sp_executesql 时可以和不能参数化的内容。

例如,谓词可以,表名不能。TOP 中的行数可以:

exec sp_executesql @stmt =
    N'SELECT TOP(@n) a, b
    FROM (VALUES(1,2)) v(a,b)',
    @params = N'@n int',
    @n = 10
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

MAXDOP 不能:

exec sp_executesql @stmt =
    N'SELECT TOP(10) a, b
    FROM (VALUES(1,2)) v(a,b)
    OPTION (MAXDOP @n)',
    @params = N'@n int',
    @n = 10
Run Code Online (Sandbox Code Playgroud)

消息 102,级别 15,状态 1,第 8 行“@n”附近的语法不正确。

我想还有更多的例子说明什么有效,什么无效。我正在寻找一个权威列表来消除反复试验。

Low*_*n M 6

背景

这些有时不起作用的原因不是特定于sp_executesql,而是变量在 SQL Server 中的工作方式。如果您使用局部变量,则您的命令将不起作用,sp_executesql而 MAXOP 也没有。

根据文档

变量只能在表达式中使用,不能代替对象名称或关键字。

表达式定义为:

... SQL Server 数据库引擎评估以获得单个数据值的符号和运算符的组合。简单表达式可以是单个常量、变量、列或标量函数。运算符可用于将两个或多个简单表达式连接成一个复杂表达式。

对于非常熟悉 SQL Server 的人来说,上述内容是有道理的,可能不需要进一步解释,但我可以看到这个定义是如何缺失的。特别是因为TOP用法看起来并不像表达式(即使为其提供的值是 one)。

更简单的事情

简化上述内容可能是愚蠢的差事,但我会试一试。

一个松散的指南,是更具描述性的和有益的可能是:

参数化值在影响查询结果时有效。

也就是说,以下内容是有效的,因为它们会影响结果(哪些行、多少行、返回什么值等),但查询本质上仍然在做同样的事情。那是因为它们被用于修改查询结果但不更改查询的表达式中。

SELECT * FROM Table WHERE Col = @n;
SELECT TOP(@N) * FROM Table;
SET @var = @n;
Run Code Online (Sandbox Code Playgroud)

而这些都是正确的,因为他们改变了查询,发动机设置的情况下,或导致不同的查询完全,等等。通常改变其中任何一个领域是通过自定义过程完成,关键字,功能,或通过改变使用的对象在查询中,因此使用表达式。

SELECT * FROM Table OPTION (MAXDOP @n);
USE @n; --Change db context
SELECT * FROM @n;
Run Code Online (Sandbox Code Playgroud)

  • `TOP(表达式)` 是在 2005 年引入的。在此之前它只是 `TOP n [ PERCENT ] [ WITH TIES ]`,其中 `n` 是一个整数文字 (2认同)