Ошибка 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;

Что-то не хватает, чтобы помочь нам придумать это

Также см

Другие вопросы по тегам