1 (изменено: Shopen, 2009-06-08 12:28:44)

Тема: Что-то непонятное с кодировками

Здравствуйте.
Имеем вот такой запрос, выполненный через phpmyadmin:

SELECT
        codeorgch,
        CONCAT(codeorgch,' + ',n_org)
FROM tbl
LIMIT 5

Результат будет примерно такой:

codeorgch     CONCAT(codeorgch,' + ',n_org)
ФЦ     ?? + 96
ФЦ     ?? + 96
ФЦ     ?? + 96
ФЦ     ?? + 96

Видно, что во втором столбце полетела кодировка, вот только непонятно почему. Если в функцию concat третьим аргументом поставить например число (или вовсе убрать его) - то все нормально:

codeorgch     CONCAT(codeorgch,' + ',11)
ФЦ     ФЦ + 11
ФЦ     ФЦ + 11
ФЦ     ФЦ + 11
ФЦ     ФЦ + 11

Также хорошо видно, что без CONCAT() значение этого же стобца (первый) показывается корректно, остальные столбцы тоже.
В других клиентах проблем нет, например когда я такой же скрипт выполняю в своём скрипте - то результат нормальный всегда. Также он нормальный из других клиентов (типа ems sql manager). Как с эту проблему побороть?


P.S. Да, от версии pma это не зависит, скачал поставил последний, 3.1.5 - там тоже самое. до этого стоял 2.11.4.
mysql - 5.0.45, windows server 2003

2

Re: Что-то непонятное с кодировками

Shopen
Конкатенация зависит от типа объединяемых значений: если все аргументы функции являются не бинарными строками, то результат будет возвращен в виде не бинарной строки; если один, или более, аргумент является бинарной строкой, то результат будет возвращен в виде бинарной строки. Важным моментом является поведение числовых значений - они переводятся в бинарный вид. То есть конкатенация строки и целого числа вернет строку в бинарном виде. Чтобы получить результат в виде не бинарной строки, следует принудительно преобразовать число в строку с помощью функции CAST().

SELECT
        codeorgch,
        CONCAT(codeorgch,' + ', CAST(n_org AS CHAR))
FROM tbl
LIMIT 5

3

Re: Что-то непонятное с кодировками

Hanut, спасибо, ваш совет помог. Ни за что бы сам не догадался до этого smile

Остался открытым только один вопрос - почему кодировки бьются только если я использую pma - а в других клиентах все работает и без CAST?

4

Re: Что-то непонятное с кодировками

Shopen
phpMyAdmin всегда возвращает значения в том виде, как они приходят от MySQL, и в данном случае строка будет бинарной. Другие клиенты могут производить предварительную конвертацию своим парсером запроса, либо возвращать данные, как есть, а там уже браузер пусть думает.

Если посмотреть клиент MySQL Query Browser, то там вывод будет бинарный, как и должно быть.

5

Re: Что-то непонятное с кодировками

Я не очень понимаю, что такое бинарный вывод, но MySQL Query Browser показывает как положено "ФЦ + 96", правда обрезает в таблице результатов цифры, но если открыть поле в доп. окошке - то там всё в порядке.

Более того, сейчас скопировал проблемную базу себе на localhost, и выполнил запрос денверовским PMA - результат нормальный. Из чего делаю вывод, что проблема все таки в настройках PMA. Из того, что очевидно различается - на сервере pma почему то уверенно пишет, что у mysql кодировка utf-8, а на локалхосте, что cp1251. Все таблицы у меня в 1251.

6

Re: Что-то непонятное с кодировками

Бинарный вывод - это вывод в виде BLOB/BINARY данных.

Если хотите конкретики, то следует указать тип данных полей, которые вы объединяете. Как я понял поле codeorgch имеет тип VARCHAR, поле n_org - INT. Если в phpMyAdmin, в блоке параметров убрать галочку "Покзаать BINARY", то увидите не вопросики, а данные в виде BINARY. Если поле codeorgch имело бы тип TEXT, то вы бы увидели вывод данных в виде BLOB.

Но это не проблема phpMyAdmin, а особенность работы с типами данных MySQL.

В Денвере старая версия phpMyAdmin и там вроде нет галочки "Показать BINARY" вовсе.

Новые версии phpMyAdmin работают с MySQL только в utf8 в независимости от кодировок таблиц и БД. То, что на Денвере показывает - значения не имеет, так как очень старое, желательно его обновить.

7

Re: Что-то непонятное с кодировками

Да, типы полей вы правильно угадали.

Всё равно не понятно. Разве в binary может быть часть данных в пределах поля, а не все оно целиком? Да, pma показывает, что результат binary, но при этом часть данных показывает корректно, а часть нет. Ведь если дело только в mysql, то запрос должен был бы вернуть только ????????, а не '?? + 96'. Т.е. часть этих самых binary-данных он показывает, а часть почему то нет. Даже если написать так -

SELECT
        codeorgch,
        CONCAT(codeorgch,' + ',n_org,' + ', 'тест')
FROM tbl
LIMIT 5

то в результате:

ФЦ     ?? + 96 + тест
ФЦ     ?? + 96 + тест

Разве это не похоже на то, что первые два символа попросту пришли в другой кодировке?

Кстати, вот такой запрос опять же возвращает нормальный результат и без указания CAST:

SELECT
        codeorgch,
        CONVERT(CONCAT(codeorgch,' + ',n_org) USING cp1251)
FROM tbl
LIMIT 5

8

Re: Что-то непонятное с кодировками

Shopen
Бинарные данные объединяются как есть, то есть в каком бы виде они не были, просто присоединяются байты, кодировки в расчет не принимаются вовсе.

ФЦ     ?? + 96 + тест - Такое будет если на главной странице phpMyAdmin выбрать сравнение utf8_general_ci, а вы попробуйте там выбрать cp1251_general_ci, и увидите вместо "тест" вопросики. Тонкостей в работе кодировок достаточно много, но исходить надо из правил написания запроса - стандарта - который говорит: что при конкатенации, для возвращения данных в виде строки, бинарные данные и числа должны быть конвертированы в строку функцией CAST().