2015-01-13 3 views
4

У меня есть значение в MySQL, который содержит апостроф () и многоточие (...):Почему Perl DBI избегает значений, полученных из 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 это делает? Могу ли я переопределить его?

+1

Это не "бежать" вопрос; это проблема с переводом символов. По умолчанию Perl использует ASCII для STDIN, STDOUT и STDERR; и да, вы можете переопределить это поведение. Кроме того, соединение с базой данных может указывать набор символов, который не поддерживает кодовые точки. И да, это тоже можно переопределить. Несколько статей, которые вы должны иметь под своим поясом: [** Абсолютный минимум Каждый разработчик программного обеспечения Абсолютно, положительно должен знать о Unicode и наборах символов (без отговорок!) **] (http://www.joelonsoftware.com/articles /Unicode.html) – spencer7593

+1

И другая статья: [** Что каждый программист абсолютно, положительно должен знать о кодировках и наборах символов для работы с текстом **) (http://kunststube.net/encoding/) – spencer7593

ответ

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

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

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

Спасибо, не знал о кодировании вывода. –

3

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

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

Спасибо, Я добавил, что DBI param, но это не имело значения. –

2

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, поэтому также может происходить перевод символов.

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


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

The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)

What Every Programmer Absolutely, Positively Needs To Know About Encodings And Character Sets To Work With Text