首页 > 解决方案 > '?' 附近的语法不正确 同时将 HTML 作为 NVARCHAR 插入

问题描述

我们有一个文本区域,用户可以在其中编写任何内容,它是一个稍后将加载的动态视图。当用户准备好保存它时,将发送 textarea 以便将其保存在数据库中。

问题是,有时有效,有时无效。它不起作用的时间是因为我们收到:

'?' 附近的语法不正确。

我们已将所有单引号替换为两个单引号,并确保它正确到达数据库。

ALTER STORED PROCEDURE dbo.SaveHtml @htmlValue NVARCHAR(MAX)
AS
DECLARE @SQL_QUERY NVARCHAR(MAX);

SET @SQL_QUERY  = N'UPDATE TEMP_TABLE SET BLOCK_1 = N{VALUE} WHERE ID = 12';

SET @SQL_QUERY = REPLACE(@SQL_QUERY,'{VALUE}', ISNULL(@htmlValue,NULL));

EXECUTE (@SQL_QUERY);

基本上这就是它的作用,我们创建一个动态 SQL,因为有些参数是动态的,但在这个例子中我省略了它。

它可以工作,但有时当用户从 Word 复制和粘贴数据时,字符串到达​​时带有 иĆÊô￴∀⠢Ĉ!ࠀސȁސ﷿ ױ﹗£΀ਮշωԊӍԊӍ̳¡﹩fȒ@† ™ IJ苏垐辀׶č靀ミ等字符,后来我们收到了指示的错误。

即使有时它与那些字符一起到达(不一定是那些完全或以相同顺序)并且它被成功保存。

对于提到的示例,如果我删除了第一个 原字符,则字符串将成功保存。

'<p class="MsoNormal" style="margin-top:0cm;margin-right:0cm;margin-bottom:0cm;
margin-left:36.2pt;text-align:justify;text-indent:-18.0pt;line-height:normal;иĆÊô￴∀⠢Ĉ!ࠀސȁސ﷿ ױ﹗£΀ਮշωԊӍԊӍ̳¡﹩fȒ@† ™ IJ囌垐輈׶č靀ミ...'

当我调试查看动态 SQL 并打印它时,它看起来像:

UPDATE TEMP_TABLE SET BLOCK_1 = N'<div class="note-editable" contenteditable="true" role="textbox" aria-multiline="true" ...' WHERE ...

因为这些是我们保存的字符串。

这目前正在生产中,因为它可以工作,但它不工作的时间是例外的。当中文、阿拉伯文和更多特殊字符出现时,我们的代码就变成了彩票。

我该如何解决这个问题?

标签: c#.netsql-serverdatabasetsql

解决方案


您没有引用您的字符串,也没有将其视为NVARCHAR. 而不是这个:

SET @SQL_QUERY = REPLACE(@SQL_QUERY,'{VALUE}', ISNULL(@htmlValue,NULL));

对于语法正确的 SQL,您需要它:

SET @SQL_QUERY = REPLACE(@SQL_QUERY,'{VALUE}', ISNULL('N''' + @htmlValue + '''','NULL'));

但是,正确且安全的方法是使用sp_executesql适当的参数,如下所示:

SET @SQL_QUERY  = N'UPDATE #TEMP_TABLE SET BLOCK_1 = @VALUE WHERE ID = 12';

EXEC sp_executesql @SQL_QUERY, N'@VALUE nvarchar(max)', @HtmlValue;

注意:调试动态 SQL 的方法是使用PRINT语句,如果您在原始 SQL 上运行,则会给出:

UPDATE TEMP_TABLE SET
    BLOCK_1 = иĆÊô￴∀⠢Ĉ!ࠀސȁސ﷿ ױ﹗£΀ਮշωԊӍԊӍ̳¡﹩fȒ@† ™ IJ囌垐輈׶č靀ミ
WHERE ID = 12

这显然是错误的,您需要:

UPDATE TEMP_TABLE SET
   BLOCK_1 = N'иĆÊô￴∀⠢Ĉ!ࠀސȁސ﷿ ױ﹗£΀ਮշωԊӍԊӍ̳¡﹩fȒ@† ™ IJ囌垐輈׶č靀ミ'
WHERE ID = 12

推荐阅读