我在使用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}
和{M1}
可以包含UTF8字符串。
例如,以下语句将返回错误:
'é¢'附近的语法不正确。字符串后面的未闭合引号'å...åå>å... <æœå>>ç§å±é™©','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:原æ‡é¢〜
M:原æ‡é¢〜[
。 。
6月20日的进一步测试参数化SQL查询不起作用,所以我尝试通过尝试隔离导致错误的字符来尝试不同的方法。经过反复试验,我设法找出了有问题的人物。
以下字符会产生错误:é¢〜
SQL语句:INSERT INTO INCOMINGLOG ([Keyword]) VALUES('题')
有趣的是,请注意返回错误税中的字符串包含“?”原始陈述中不存在的字符。
错误:字符串'é¢?)后的未闭合引号。 'é¢?)'附近的语法不正确。
如果我在罪魁祸首之后立即放置一些拉丁字符,则不会有错误。例如,INSERT INTO INCOMINGLOG ([Keyword]) VALUES('题Ok')
可以正常工作。注意:它不适用于所有字符。
答案 0 :(得分: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;
缺少帮助我们解决这个问题的东西
另见