Sql server 将UTF8字符串插入SQL Server 2008表时发生SQL错误
我试图使用Zeosdb原生SQL Server库从Delphi 7应用程序将包含UTF-8编码的汉字和标点符号的字符串插入SQL Server 2008表(默认安装)时遇到问题 我记得在过去,即使使用PHP和其他方法,我在将UTF8字符串插入SQL Server时也遇到问题,所以我相信这个问题不是Zeosdb独有的 这种情况并非总是发生,有些UTF8编码的字符串可以成功插入,但有些不能。我搞不清楚是什么导致了失败 表架构:Sql server 将UTF8字符串插入SQL Server 2008表时发生SQL错误,sql-server,delphi,utf-8,Sql Server,Delphi,Utf 8,我试图使用Zeosdb原生SQL Server库从Delphi 7应用程序将包含UTF-8编码的汉字和标点符号的字符串插入SQL Server 2008表(默认安装)时遇到问题 我记得在过去,即使使用PHP和其他方法,我在将UTF8字符串插入SQL Server时也遇到问题,所以我相信这个问题不是Zeosdb独有的 这种情况并非总是发生,有些UTF8编码的字符串可以成功插入,但有些不能。我搞不清楚是什么导致了失败 表架构: CREATE TABLE [dbo].[incominglog](
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]
INSERT INTO INCOMINGLOG ([Number], [Keyword], [Message], [MessagePart1], [Datetime], [Recipient])
VALUES('{N}', '{KEYWORD}', '{M}', '{M1}', '{TIMESTAMP}', '{NAME}')
SQL语句模板:
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]
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',''
注意:请忽略实际字符,因为复制和粘贴后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所示,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','')
INSERT INTO INCOMINGLOG ([Keyword],[Message]) VALUES(:KEYWORD,:M)
。
回复gbn的答案:我尝试使用参数化SQL,但仍然遇到“字符串后未闭合引号”错误
对于新的测试,我使用了一个简化的SQL语句:
INSERT INTO INCOMINGLOG ([Number],[Keyword],[Message],[MessagePart1],[Datetime],[Recipient]) VALUES('+6590621005',N'åŽŸæ ‡é¢˜',N'åŽŸæ ‡é¢˜ [全力克æœ?å››ç§?å?±é™© å?šå†³æ‰«é™¤ä½œé£Žä¹‹å¼Š]',N'[全力克æœ?å››ç§?å?±é™©','2013-06-19','')
INSERT INTO INCOMINGLOG ([Keyword],[Message]) VALUES(:KEYWORD,:M)
为上述语句返回的错误:
INSERT INTO INCOMINGLOG ([Number],[Keyword],[Message],[MessagePart1],[Datetime],[Recipient]) VALUES('+6590621005',N'åŽŸæ ‡é¢˜',N'åŽŸæ ‡é¢˜ [全力克æœ?å››ç§?å?±é™© å?šå†³æ‰«é™¤ä½œé£Žä¹‹å¼Š]',N'[全力克æœ?å››ç§?å?±é™©','2013-06-19','')
INSERT INTO INCOMINGLOG ([Keyword],[Message]) VALUES(:KEYWORD,:M)
“ŽƂæ”附近的语法不正确。后面的未闭合引号
字符串“”)”
对于info,关键字和M的值为:
关键词:中国
M:[
。
.
6月20日的进一步测试参数化SQL查询不起作用,因此我尝试了另一种方法,尝试隔离导致错误的字符。经过反复试验,我成功识别出了有问题的字符
以下字符产生一个错误:戥
SQL语句:插入到INCOMINGLOG([Keyword])值('e')
有趣的是,请注意返回错误税中的字符串包含原始语句中不存在的“?”字符
错误:字符串“é×?”后的引号未闭合。“é×?”附近的语法不正确
如果我在罪魁祸首字符后立即放置一些拉丁字符,则不会出现错误。例如,
插入INCOMINGLOG([Keyword])值('éOk')
工作正常。注意:它不适用于所有字符。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;
缺少一些东西来帮助我们解决这个问题
也看到
{KEYWORD}
包含引号?错误消息似乎表明了这一点。我建议在不可能发生此类错误的情况下使用参数化查询。参数化查询也会阻止SQL注入。嗨,mjn,我已将所有引号加倍。我怀疑引号可能不是UTF8字符串中唯一的非法字符。您的SQL插入INCOMINGLOG([关键字])值('
在中对我有效SSMS@gbn我不确定,但我认为当你复制到SSMS时,情况就不一样了,可能是编码发生了变化。唯一的测试方法是使用代码——我已经创建了PHP代码,你可以从中下载。有两个PHP文件,一个是有效的,另一个是失败的。顺便说一句,本文说的是MSSQL没有支持UTF-8-。以前,在使用UTF-8之前,我将UTF-8转换为widestring,但从SSMS查看时它们显示为问号。感谢gbn,我尝试使用参数化SQL,但仍然存在相同的错误,请检查我在原始问题中的注释。我喜欢指出我的SQL Server db使用中文作为排序规则。我使用SQL management studio手动在GBK编码中插入相同的数据没有问题,但我的软件使用UTF8插入。@Joshua:请添加Delphi代码。这可能是一个客户端错误,而不是SQL错误,因为suchI已经为此创建了另一个问题,其中有一个链接,您可以从中下载我制作的测试程序-单击。重新开始产生问题,取消注释“//作为utf8插入”,并删除编辑框中的“ok”。