не может прочитать строки utf8 из БД MySQL клиентом odbc

0

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

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

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

Знаете ли вы о проблемах с кодировкой с libodbС++?

EDIT: просто протестировал это с помощью "чистого" клиента odbc (отвратительно...), работает нормально. Странно, поскольку libodbС++ - это просто оболочка для odbc, я ожидаю, что это не повлияет на данные. В любом случае, подозреваемый является библиотекой libodbС++.

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^@
Теги:
odbc
character-encoding
utf-8

2 ответа

1
Лучший ответ

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

1

Я не знаю, ваша проблема такая же, как у меня. Я пытался получить результат поиска из базы данных 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

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

  • 0
    Благодарю. да, _utf8 является представителем (как здесь dev.mysql.com/doc/refman/5.1/en/charset-literal.html ). Недостатком такого подхода является то, что преобразование выполняется во время выполнения запроса и занимает много времени. И не беспокойтесь о своем английском - это не родной язык для большинства из нас :)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню