Ошибка SQL при вставке строки UTF8 в таблицу SQL Server 2008
У меня возникают проблемы при попытке вставить строки, содержащие китайские символы и знаки препинания в кодировке UTF-8, в таблицу SQL Server 2008 (установка по умолчанию) из моего приложения Delphi 7 с использованием собственной библиотеки Zeosdb SQL Server.
Я помнил, что в прошлом у меня были проблемы с вставкой строки UTF8 в SQL Server даже с использованием PHP и других методов, поэтому я считаю, что эта проблема не уникальна для 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:
Ключевое слово:åŽŸæ ‡é¢˜
М:åŽŸæ ‡é¢˜ [
,,,
Дальнейшие тесты 20 июня Параметризованный SQL-запрос не работает, поэтому я попробовал другой подход, пытаясь выделить символ, вызвавший ошибку. После проб и ошибок мне удалось выявить проблемного персонажа.
Следующий символ выдает ошибку: 题
Оператор SQL: INSERT INTO INCOMINGLOG ([Keyword]) VALUES('题')
Интересно отметить, что строка в налоге на ошибку возврата содержит "?" персонаж, которого не было в исходном утверждении.
Ошибка: незакрытая кавычка после символьной строки 'é¢?)'. Неверный синтаксис рядом с 'é¢?)'.
Если бы я поместил несколько латинских символов сразу после символа-преступника, ошибки не будет. Например, INSERT INTO INCOMINGLOG ([Keyword]) VALUES('题Ok')
работает нормально Примечание: это не работает со всеми персонажами.
1 ответ
Есть '
символы в 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;
Что-то не хватает, чтобы помочь нам придумать это
Также см