sp_executesql 在 SET 语句上使用 OUTPUT 参数

sp_executesql with OUTPUT Parameter on SET statement

我想用sp_executesql为sp_send_dbmail设置@email_body

为什么?

之前,我将参数直接连接到 @email_body,这很容易发生 SQL 注入。 像这样

SET @email_body = 'some html' + @id + 'some html' + @name + 'some html';

SQL 注入是可能的,因为我们无法控制输入。

我做了什么?

所以上面只是一个例子 我的查询看起来很像这样

DECLARE @sql NVARCHAR(MAX);
DECLARE @email_body VARCHAR(max);
DECLARE @ParamDef NVARCHAR(MAX);
DECLARE @id INT;
DECLARE @name NVARCHAR(MAX);
DECLARE @status NVARCHAR(MAX);

-- select statement to input have input in @id, @name and @status from sometable;

SET @sql = N'SET @email_bodyOUT = CASE @status  
                    WHEN ''A'' THEN ''SOME HTML'' + @id + ''SOME HTML'' + @name + ''SOME HTML'' 
                    WHEN ''B'' THEN ''SOME HTML'' + @id + ''SOME HTML'' + @name + ''SOME HTML'' 
                    WHEN ''C'' THEN ''SOME HTML'' + @id + ''SOME HTML'' + @name + ''SOME HTML'' END';

SET @ParamDef = N'@email_bodyOUT VARCHAR(MAX) OUTPUT
        , @status NVARCHAR(MAX)
        , @id INT
        , @name NVARCAHR(MAX)';

EXECUTE sp_executesql @sql 
            , @ParamDef
            , @email_bodyOUT = @email_body OUTPUT
            , @status = @status
            , @id = @id 
            , @name = @name;
SELECT @email_bodyOUT;
--executing sp_send_dbmail and send email

但是 @email_body 中没有任何附件并且邮件是空的。 当我 运行 像这样的简单查询 sp_executesql

时它工作正常
 DECLARE @First_Name NVARCHAR(200) = 'abc';
 EXEC sp_executesql N'
         declare @HTML nvarchar(max) =  ''Hi'' + @FN + '' , Rest of HTML email :) :)  ''
         SELECT @HTML',
   N'@FN VARCHAR(8000)',
   @First_Name;

提前感谢您的帮助:)

发现问题,这是由于参数之一是 Null,导致 @emailbody 为空。通过 ISNULL 函数修复它。