我一直盯着自己看。它开始是一个更复杂的过程,但我已经将它剥离到裸露的骨头上,试图让它运行。这是当前代码:
DECLARE @sql NVarchar(MAX) = '
CREATE PROCEDURE dbo.Test
AS
BEGIN
SELECT 1, @num;
END'
EXEC [sp_executesql] @sql, N'@num int', @num = 1;
它只是拒绝。值得一提的是,如果我在没有参数部分(@sql
作为函数的唯一参数sp_executesql
)的情况下运行代码,它运行良好。我尝试过其他语法替代方案,例如
EXEC [sp_executesql] @sql, N'@num int', 1;
和
DECLARE @params NVarchar(1000) = '@num int';
EXEC [sp_executesql] @sql, @params, 1;
我的参数规范有什么问题?
编辑 1:包含错误消息
Msg 156, Level 15, State 1, Line 2
Incorrect syntax near the keyword 'PROCEDURE'.
您似乎期望这些参数最终会被视为字符串插值参数。
他们不会。
实现类似于您想要的东西的一种方法是简单地参数化存储过程
然后,当您执行它时,您会提供所需的值。
如果您确实希望该过程最终
@num
被替换为硬编码1
,您可以使用。如果你走这条路,请注意 SQL 注入。
此外,您需要注意参数/占位符名称和替换顺序,因此如果您有占位符
@num
并且需要先替换@number
该占位符。@number
由于 sql 注入漏洞,您应该避免使整个调用动态化。
您的过程还需要接受您在动态 sql 调用中指定的参数
参数化动态 sql 的正确方法是:
参数化动态 sql 还允许重用过程缓存中的计划,并且对服务器来说效率更高。如果你遇到过没有参数化的动态 sql 并且因为它在第三方软件中而无法修改,你也可以使用计划指南。