Почему Perl DBI экранирует значения, полученные из MySQL?

У меня есть значение в MySQL, которое содержит апостроф () и многоточие (...):

$ /bin/echo "select alias from url_alias where source = 'node/12024'" | \
  mysql --skip-column-names -D cat36ia_d7prod

Выход:

forum/technical-discussion/nagging-questions-i’ve-been-too-embarrassed-ask…

Когда я получаю значение с помощью Perl DBI а также DBD::mysql, значение было изменено:

$ perl -MDBI -MDBD::mysql -e
      '$dbh=DBI->connect( "DBI:mysql:database=my_db",nick );
       $v=$dbh->selectrow_array(qq|select alias from url_alias where source = "'node/12024'"|);
       print "$v\n";'

Выход:

forum/technical-discussion/nagging-questions-i?ve-been-too-embarrassed-ask?

Почему Perl делает это? Могу ли я переопределить это?

3 ответа

Решение
  1. Скажите Perl, как кодировать вывод.

    use open ':std', ':encoding(UTF-8)';
    
  2. Получить данные из базы данных в виде текста с помощью

    DBI->connect("DBI:mysql:database=my_db", $user, $pass, {
       mysql_enable_utf8 => 1,
    })
    

Вы, вероятно, должны указать DBI использовать UTF8 при обращении к базе данных.

$dbh=DBI->connect(
   'DBI:mysql:database=my_db', $user, $pass,
   { mysql_enable_utf8 => 1 }
);

Q: Почему Perl делает это? Могу ли я переопределить это?

Этого не избежать. Это признак проблемы перевода набора символов. Знак вопроса - это символ по умолчанию, используемый, когда кодовая точка не отображается ни на какой другой символ в целевом наборе символов.


Короткий ответ относительно того, почему Perl делает это, может быть следующим: по умолчанию Perl выводит в STDOUT, используя набор символов ascii. Поскольку ASCII поддерживает только кодовые точки до U+00EF, все остальные кодовые точки (например, символы от 128 до 255) переводятся в знак вопроса.

Краткий ответ о том, как переопределить это поведение, может быть следующим: укажите, что STDIN, STDOUT и STDERR используют кодировку utf8, а не ascii, включив такую ​​строку в вашу perl-программу:

use open qw(:std :utf8);

Другая потенциальная проблема - настройка сеанса MySQL. character_set_client переменная; соединение с базой данных может использовать latin1 набор символов, но набор символов базы данных / сервера / столбца может быть utf8, так что там также может происходить перевод набора символов.

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


В качестве отправной точки для понимания наборов символов, вот две ссылки, которые вы должны иметь под своим поясом:

Абсолютный минимум Каждый разработчик программного обеспечения Абсолютно, положительно должен знать о Unicode и наборах символов (никаких оправданий!)

Что каждый программист абсолютно, положительно должен знать о кодировках и наборах символов для работы с текстом

Другие вопросы по тегам