Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > Проблема с UTF8 и MSSQL


Автор: infarch 16.9.2019, 13:57
Здравствуйте.

Я работаю над сайтом, который использует Убунту и Апач в качестве вебсервера, и Microsoft SQL Server как базу данных. Коннектимся через freetds+unixODBC. Все работало нормально, но вот пришло время переезда и сейчас мы тестируем все это в Azure. Для этого детачнули базу тестового сервера и приатачили в азуре. Поставили последнюю версию freeetds / odbc, сделали чекаут сайта из репозитория. Тут и выплыл занятный баг.
Для начала, utf8 строка которая была в старой базе выглядит в SSMS правильно, но отображается как "????" в веб интерфейсе: https://www.screencast.com/t/86kYD7eO
Если создать новую строку через веб интерфейс, она выглядит нормально на сайте, но криво в базе: https://www.screencast.com/t/YkCU14OD
Запуская на убунте (в терминале) скрипт для вставки тестовой строки, в базе получаю хорошее значение: https://www.screencast.com/t/TBjOkYTC3
Почти идентичный код выполненный через Апач создает кривую строку в базе.
Я свои идеи практически исчерпал, прошу помощи коллективного разума! Что может быть не так???

пс: непосредственно перед отправкой подумал что скрипт в терминале и Апач работают от разных пользователей. Не знаю как это может влиять но это наверно единственное отличие. Как проверить такую догадку? Ну не силен я в убунтах, большей частью програмист.

Автор: arto 16.9.2019, 16:19
посмотрите в http заголовке кодировку.

Автор: infarch 16.9.2019, 16:37
Посмотрел: https://www.screencast.com/t/oE53VuGjlG
Вместо знаков вопроса там должна быть кирилица. Я сомневаюсь что в заголовках дело. Вызывая скрипт из терминала я получаю нормальную запись в базе, он-же через апач - баг! Мне тут подсказали что может терминал и мод-перл используют разные версии перла. На первый взгляд они одинаковые, но может разница в билдах... 
https://www.screencast.com/t/0GgauypTt8sL
https://www.screencast.com/t/v1dg1Ilxg

Автор: arto 17.9.2019, 11:29
Скорее всего из базы вы получаете данные не в utf-8 кодировке.
Какая у вас там локальная кодировка?

Автор: infarch 17.9.2019, 12:36
"Там" - это где? В базе строки nvarchar. Сохранены они правильно, в utf8, что и видно в SSMS. Но вот читаются как-то плохо. И проблема не только с чтением. Я уже писал про вставку и мне кажется тут проще всего накопать корень зла. 

У меня есть перл скрипт для вставки кириличной строки в базу.
Когда я его выполняю из терминала командой 'perl uodbc.pl', он вставляет правильное значение. 
Запускал от имени www-data ("sudo -H -u www-data bash -c 'perl uodbc.pl'"): тоже правильный результат. 
Скопировал текст скрипта, вставил в файлы сайта и вызвал через Апач - вставка НЕПРАВИЛЬНАЯ. 
Закоментировал вставку на сайте, а вместо нее вызвал оригинальный скрипт: "system('perl /home/Docia/uodbc.pl')". Пинаю это через Апач - вставка НЕПРАВИЛЬНАЯ. 
Усложнил ситуацию: из терминала вызываю скрипт который запускает файл с сайта который выполняет вышеуказанный system. Вставка правильная!

Как тут ни крути, а результат вырисовавается один. Один и тот же перл скрипт вставляет в базу правильное значение когда вызван ручками через терминал, и неправильное - когда вызван апачем. В апаче я юзаю mod-perl. Перл в системе вроде бы только один. Пока нет идей как все это пофиксать :(

Автор: arto 17.9.2019, 22:31
следите за кодировками.
с MSSQL не работал, только с Sybase, проблем не было.

Вы какой метод используете для работы с базой и какой драйвер?

Автор: infarch 18.9.2019, 09:57
Драйвер freeTDS + unixODBC

Все работало отлично, пока мы не начали переезжать в Азуру. Сейчас разворачиваем тестовый сайт на их виртуалках и все ставим с нуля. И по выплыла такая проблема.

Автор: arto 18.9.2019, 14:22
DBD & DBI::ODBC ?

какая кодировка в базе (UTF-7 UTF-8 UTF-16 UTF-16BE UTF-16LE UTF-32 UTF-32BE UTF-32LE)?

Автор: infarch 18.9.2019, 17:18
Этот вопрос меня несколько смутил. Насколько я знаю, поля nchar/nvarchar/ntext хранят юникодные строки, а какой способ кодирования выбирает для этого база - хз... Я их просто читаю и пишу. Perl передает и принимает раскодированные строки.
Однако проблема решилась! Я изменил значение переменной LANG для апача в "/etc/apache2/envvars: export LANG=en_us.UTF-8
До этого значение переменной было С, и этого хватало для старого сервера. В новом что-то не срослось. Но теперь все отлично!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)