1

我在尝试使用 Zeosdb 本机 SQL Server 库从我的 Delphi 7 应用程序将包含 UTF-8 编码的中文字符和标点符号的字符串插入 SQL Server 2008 表(默认安装)时遇到问题。

我记得过去我在使用 PHP 和其他方法将 UTF8 字符串插入 SQL Server 时遇到问题,所以我相信这个问题不是 Zeosdb 独有的。

它不会一直发生,一些 UTF8 编码的字符串可以成功插入,但有些不能。我无法弄清楚导致失败的字符串中的内容。

表架构:

CREATE TABLE [dbo].[incominglog](
    [number] [varchar](50) NULL,
    [keyword] [varchar](1000) NULL,
    [message] [varchar](1000) NULL,
    [messagepart1] [varchar](1000) NULL,
    [datetime] [varchar](50) NULL,
    [recipient] [varchar](50) NULL
) ON [PRIMARY]

SQL语句模板:

INSERT INTO INCOMINGLOG ([Number], [Keyword], [Message], [MessagePart1], [Datetime], [Recipient]) 
VALUES('{N}', '{KEYWORD}', '{M}', '{M1}', '{TIMESTAMP}', '{NAME}')

参数{KEYWORD},可以包含{M}UTF8{M1}字符串。

例如,以下语句将返回错误:

'é¢' 附近的语法不正确。字符串 'å...¨åŠ›å...‹æœå››ç§å±é™©','2013-06-19 17:07:28','')' 后的非闭合引号。

INSERT INTO INCOMINGLOG ([Number], [Keyword], [Message], [MessagePart1], [Datetime], [Recipient]) 
VALUES('+6590621005', '题', '题 [全力克æœå››ç§å±é™© åšå†³æ‰«é™¤ä½œé£Žä¹‹å¼Š]', '[全力克æœå››ç§å±é™©','2013-06-19 17:07:28', '')

注意:请忽略实际字符,因为 utf8 编码在复制和粘贴后丢失。

我也尝试过使用NVARCHAR而不是VARCHAR

CREATE TABLE [dbo].[incominglog](
    [number] [varchar](50) NULL,
    [keyword] [nvarchar](max) NULL,
    [message] [nvarchar](max) NULL,
    [messagepart1] [nvarchar](max) NULL,
    [datetime] [varchar](50) NULL,
    [recipient] [varchar](50) NULL
) ON [PRIMARY]

并尝试将 SQL 语句修改为:

INSERT INTO INCOMINGLOG ([Number],[Keyword],[Message],[MessagePart1],[Datetime],[Recipient]) VALUES('{N}',N'{KEYWORD}',N'{M}',N'{M1}','{TIMESTAMP}','{NAME}')

他们也不工作。我将不胜感激任何指针。谢谢。

已编辑:如下面的 marc_s 所示,N 前缀必须在单引号之外。在我的实际测试中是正确的,最初的陈述是一个错字,我已经更正了。

带有 N 前缀的测试也返回了错误:

'åŽŸæ ‡é¢' 附近的语法不正确。字符串 'å...¨åŠ›å...‹æœ?å››ç§?å?±é™©','2013-06-19 21:22:08','')' 后的非右引号。

SQL 语句:

INSERT INTO INCOMINGLOG ([Number],[Keyword],[Message],[MessagePart1],[Datetime],[Recipient]) VALUES('+6590621005',N'原标题',N'原标题 [全力克�四��险 �决扫除作风之弊]',N'[全力克�四��险','2013-06-19','')

. .

回复 gbn 的回答:我尝试过使用参数化 SQL,但仍然遇到“字符串后未闭合引号”错误。

对于新测试,我使用了简化的 SQL 语句:

INSERT INTO INCOMINGLOG ([Keyword],[Message]) VALUES(:KEYWORD,:M)

上述语句返回的错误:

'åŽŸæ ‡é¢' 附近的语法不正确。字符串 '')' 后面的非闭合引号。

对于信息,KEYWORD 和 M 的值是:

KEYWORD:原æ‡é¢~</p>

M:原æ‡é¢~ [

. . .

6 月 20 日参数化 SQL 查询的进一步测试不起作用,因此我尝试了一种不同的方法,尝试隔离导致错误的字符。经过反复试验,我设法确定了有问题的角色。

以下字符产生错误:é¢~

SQL 语句:INSERT INTO INCOMINGLOG ([Keyword]) VALUES('题')

有趣的是,请注意返回错误税中的字符串包含一个“?” 原始语句中不存在的字符。

错误:字符串 'é¢?)' 后面的未闭合引号。'é¢?)' 附近的语法不正确。

如果我在罪魁祸首之后立即放置一些拉丁字符,就不会出错。例如,INSERT INTO INCOMINGLOG ([Keyword]) VALUES('题Ok')工作正常。注意:它不适用于所有字符。

4

1 回答 1

3

UTF-8 中存在'异常终止 SQL 的字符。

经典的 SQL 注入。

使用适当的参数化,基本上不是字符串连接。

编辑,在问题更新后...

如果没有 Delphi 代码,我认为我们无法为您提供帮助
。所有 SQL 端代码都可以正常工作。例如,这适用于 SSMS

DECLARE @t TABLE ([Keyword] nvarchar(100) COLLATE Chinese_PRC_CI_AS);
INSERT INTO @t ([Keyword]) VALUES('题');
INSERT INTO @t ([Keyword]) VALUES(N'题');
SELECT * FROM @t T;

缺少一些东西来帮助我们解决这个问题

另见

于 2013-06-19T11:31:12.207 回答