Почему 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 ответа
Скажите Perl, как кодировать вывод.
use open ':std', ':encoding(UTF-8)';
Получить данные из базы данных в виде текста с помощью
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
, так что там также может происходить перевод набора символов.
И можно указать набор символов, который будет использоваться в соединении с базой данных, чтобы избежать нежелательного перевода набора символов.
В качестве отправной точки для понимания наборов символов, вот две ссылки, которые вы должны иметь под своим поясом: