2016-06-15 2 views
0

У меня есть таблица MySQL с столбцом VARCHAR(100) с использованием сопоставления utf8_general_ci.Как вставить произвольные двоичные данные в столбец VARCHAR?

Я могу видеть строки, в которых этот столбец содержит произвольные последовательности байтов (т.е. данные, содержащие недопустимые последовательности символов UTF8), но я не могу понять, как написать инструкцию UPDATE или INSERT, которая позволяет вводить данные такого типа ,

Например, я попытался следующие:

UPDATE DataTable SET Data = CAST(BINARY(X'16d7a4fca7442dda3ad93c9a726597e4') AS CHAR(100)) WHERE Id = 1; 

Но я получаю ошибку:

Incorrect string value: '\xFC\xA7D-\xDA:...' for column 'Data' at row 1 

Как я могу написать заявление INSERT или UPDATE, которая обходит параметры сортировки столбца-адресата, позволяя мне вставлять произвольные последовательности байтов?

+1

[Абсолютный минимум Каждый разработчик программного обеспечения Абсолютно, положительно должен знать о Unicode и наборах символов (никаких оправданий!) Www.joelonsoftware.com/articles/ Unicode.html] (http://www.joelonsoftware.com/articles/Unicode.html) и [Что каждый программист абсолютно, положительно должен знать о кодировках и наборах символов для работы с текстом kunststube.net/encoding/](http : //kunststube.net/encoding/) – spencer7593

+0

Я знаю, как работает кодировка символов. Я не могу понять, как заставить MySQL игнорировать кодировку в INSERT или UPDATE. –

+0

С какими данными вы работаете? Вы пытались изменить свою сортировку на расширенный utf8? (Utf8mb4_general_ci). –

ответ

0

Считаете ли вы использование одного из типов данных Blob вместо varchar? Я считаю, что это избавит вас от боли.

EDIT: В качестве альтернативы существуют функции HEX and UNHEX, которые поддерживает MySQL. Hex принимает либо str, либо числовой аргумент и возвращает шестнадцатеричное представление вашего аргумента в виде строки. Unhex делает обратный; взяв шестнадцатеричную строку и вернув двоичную строку.

+0

Это не вариант. Эта таблица уже существует и находится в интенсивном использовании. Я просто не могу понять, как данные попали туда. –

+1

Encode Base64 создаст строку, которая может перейти в varchar (max). –

+0

@JohnCappelletti: Я не спрашиваю, как получить строку с кодировкой base64 в столбце. –

-2

Вы должны base64 кодировать значение заранее, так что вы можете создать действительный SQL с ним:

UPDATE DataTable SET Data = from_base64('mybase64-encoded-representation-of-my-value') WHERE Id = 1; 
0

Короткий ответ, что это не должно быть возможным, чтобы вставить значения с недопустимыми символами UTF8 в VARCHAR столбца, объявленного для использования символов UTF8.

Это цель дизайна MySQL, чтобы запретить недопустимые значения. Когда есть попытка сделать это, MySQL вернет либо ошибку, либо предупреждение, либо (более снисходительно?) Молча урезает предоставленное значение при первом недействительном символе.

Более обычное разнообразие проблем с символами связано с тем, что MySQL выполняет преобразование символов, когда преобразование символов не требуется.

Но проблема, о которой вы сообщаете, заключается в том, что недопустимые символы были вставлены в столбец UTF8. Это похоже на кодирование latin1 (ISO-8859), и требуется преобразование символов, но было выполнено , но не.

Насколько это касается ... Я считаю, что это возможно в более ранних версиях MySQL. Я считаю, что можно было присвоить значение BINARY, а затем деформировать его в CONVERT(... USING UTF8), а MySQL не будет выполнять проверку набора символов. Я не знаю, возможно ли это с текущими соединителями MySQL.

Если возможно, то это (IMO) ошибка в соединителе.

Единственный способ, которым я могу думать о том, чтобы обойти эту проверку/проверку набора символов, это заставить сервер MySQL доверять клиенту и определить, что проверка набора символов не требуется. (Это также означает, что сервер MySQL не будет делать преобразование символов, клиент лежит на сервере, клиент говорит серверу, что он снабжает действительные символы UTF8.

В принципе, клиент будет сообщать серверу «Привет, сервер, я собираюсь отправлять кодировки символов UTF8».

И сервер говорит: «Хорошо, тогда я не буду преобразовывать символы, потому что мы согласны. И я просто верю, что то, что вы отправляете, является допустимым UTF8».

И тогда клиент озорно хихикает: «Хе-хе, я соврал. Я фактически отправляю кодировки символов, которые недействительны UTF8».

И я думаю, что гораздо более вероятно, чтобы быть в состоянии достичь такого вреда, используя подготовленные заявления со старой школой MySQL C API (mysql_stmt_prepare, mysql_stmt_execute), снабжая nvalid UTF8 кодировок в качестве значений параметров строки связывания. (Бремя на самом деле на клиенте, чтобы предоставить действительные значения для параметров привязки.)

Смежные вопросы