не может прочитать строки utf8 из БД MySQL клиентом odbc - PullRequest
0 голосов
/ 30 января 2011

У меня есть БД с набором символов по умолчанию в utf8 и таблица, содержащая строки с не-ascii символами. Я могу правильно прочитать данные с помощью клиентской программы mysql и клиентской программы isql odbc (см. Примеры ниже). Однако, когда я читаю таблицу в своем клиенте C ++ с помощью оболочки libodbc ++ odbc, я получаю мусор.

Любопытно, что до сих пор я использовал настройки MySql по умолчанию, то есть latin1 кодировку, но на самом деле данные содержали строки utf8. Таким образом, я получаю utf8 нормально. Я изменил базу данных на utf8, чтобы можно было использовать параметры сортировки utf8_bin.

Поскольку я использую set names utf8 в клиенте, я не ожидаю, что между клиентом и сервером произойдет преобразование кодировки. Я ошибся?

Известны ли вам проблемы с кодировкой в ​​libodbc ++?

РЕДАКТИРОВАТЬ : только что проверил это с "чистым" клиентом odbc (отвратительно ...), работает нормально. Странно, поскольку libodbc ++ - это просто оболочка для odbc, я ожидаю, что это не окажет такого влияния на данные. В любом случае подозреваемым является библиотека libodbc ++.

mysql> show full columns from tbl_list_domains;
+-------+-----------+-----------+------+-----+---------+-------+---------------------------------+---------+
| Field | Type      | Collation | Null | Key | Default | Extra | Privileges                      | Comment |
+-------+-----------+-----------+------+-----+---------+-------+---------------------------------+---------+
| word  | char(100) | utf8_bin  | NO   | PRI | NULL    |       | select,insert,update,references |         | 
+-------+-----------+-----------+------+-----+---------+-------+---------------------------------+---------+


$ mysql -u mysql navajoLocal <<< "set names utf8; select * from tbl_list_domains order by word limit 30" > out

Файл out выходит хорошо:

word
aa
ab
ac
ad
ae
...etc.

Использование isql клиента odbc:

echo -e "set names utf8 \n select * from tbl_list_domains order by word limit 30" |isql mysql3-test -v -b -x0x20 > out

все еще хорошо.

однако это:

int main()
{
 ConnectionPtr conn = ConnectionPtr( DriverManager::getConnection("Driver=mysql3;database=navajoLocal;server=localhost;user=mysql;option=3;socket=/var/lib/mysql/mysql.sock") );

 StatementPtr st = StatementPtr( conn->createStatement() );
 st->executeUpdate("set names utf8 collate utf8_bin");

 ResultSetPtr res = ResultSetPtr( st->executeQuery("select word from tbl_list_domains order by word limit 30") );

 string s;
 while (res->next()) {
  s = res->getString(1);
  cout << s << endl;
 }
}

выдает это:

a^@
a^@
a^@
a^@

Ответы [ 2 ]

1 голос
/ 31 января 2011

Ну, нашел виновных - это библиотека libodbc++, как говорится в редакции.Собираюсь писать авторам.Решением было бы заменить его соединителем MySql C ++.Они оба смоделированы после JDBC, поэтому изменение невелико.Надеюсь, я не буду менять БД в ближайшее время ...

1 голос
/ 30 января 2011

Я действительно не знаю, является ли ваша проблема такой же, как моя.Я пытался получить результат поиска из базы данных utf8_bin, используя PHP и MySQL DB, но utf8_bin очень строги, когда говорят о похожих символах (например, e ë ë).Таким образом, когда запрос используется без надлежащих символов utf8 и / или регистра, он не возвращает результаты или, по крайней мере, ожидаемые.Итак, мой оракул, который Google показал в документах MySQL, решил для меня использование _utf8 (обратите внимание на подчеркивание) и collate utf8_unicode_ci в предложении SELECTS WHERE, например:

SELECT field1,field2,field3
FROM `table1`
WHERE `table`.`field2` LIKE _utf8 '%$q%' collate utf8_unicode_ci

Надеюсь, это решит вашу проблему.PS: извините за мой английский.Это не мой родной язык.

...