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”附近的语法不正确。
我想还有更多的例子说明什么有效,什么无效。我正在寻找一个权威列表来消除反复试验。
这些有时不起作用的原因不是特定于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)