[Perl] DBI DBD::MySQL et UTF-8

Dominique Asselineau asseline at telecom-paristech.fr
Mer 29 Juin 12:17:28 CEST 2016


Bonjour,

Tout d'abord, désolé pour le message d'hier-soir, pour lequel il y avait un problème dans l'encodage la pièce jointe.
Et puis j'avais omis le résultat que j'obtiens avec l'ECM.


Paul Gaborit wrote on Tue, Jun 28, 2016 at 04:35:21PM +0200
> Le 28/06/2016 14:45, Dominique Asselineau a écrit :
> >Paul Gaborit wrote on Sat, Jun 25, 2016 at 08:55:43AM +0200
> >>Le 24/06/2016 15:50, Dominique Asselineau a écrit :
> >>>Je passe tout mes codes en Unicode (encodage UTF8) et je rencontre des
> >>>difficultés avec DBI/DBD::MySQL.
> >>>
> >>>Avec le paramètre "mysql_enable_utf8=1" passé à la connexion, l'entrée
> >>>et l'encodage des données dans un colonne de type varchar se passe bien,
> >>>tout semble correctement encodé dans la base de données (vérifié avec
> >>>un client mysql en console).  Maintenant, quand je cherche à récupérer
> >>>les données, stockées dans du varchar donc, elles restent à l'état de
> >>>chaîne d'octets et ne sont donc pas décodées.  En clair, les
> >>>opérations entrée et sortie ne sont pas symétriques.
> >>
> >>Un appel à
> >>
> >>	$dbh->do('set names utf8');
> >>
> >>devrait aider...
> >
> >Malheureusement non.  Le résultat est toujours une chaîne d'octets
> >qu'il faut explicitement décoder par Encode::decode_utf8 si et
> >seulement si elle provient d'un type SQL char, varchar ou text.
> 
> Pourtant la documentation de DBD::mysql est claire :
> 
> ========
> mysql_enable_utf8
> 
>   This attribute determines whether DBD::mysql should assume
>   strings stored in the database are utf8. This feature defaults
>   to off.
> 
>   When set, a data retrieved from a textual column type (char,
>   varchar, etc) will have the UTF-8 flag turned on if
>   necessary. This enables character semantics on that string. You
>   will also need to ensure that your database / table / column is
>   configured to use UTF8. See Chapter 10 of the mysql manual for
>   details.
> 
>   Additionally, turning on this flag tells MySQL that incoming
>   data should be treated as UTF-8. This will only take effect if
>   used as part of the call to connect(). If you turn the flag on
>   after connecting, you will need to issue the command "SET NAMES
>   utf8" to get the same effect.
> 
>   This option is experimental and may change in future versions.
> =======
> 
> Depuis longtemps, j'utilise DBI et MySQL avec des données en UTF8 sans aucun
> souci. Vos données ne souffriraient-elles pas de double encodage? C'est
> courant lorsqu'on a fait plusieurs tests successifs.

Non.  J'ai eu ce problème au début effectivement, en manipulant mal le
paramètre mysql_enable_utf8 qu'on doit passer dès la connexion.

Et puis je "delete" à chaque fois pour être justement sûr de mes données.

> 
> Pour en être sûr, je vous engage à recréer une base vide, à créer des tables
> avec des champs en UTF8 (il faut le spécifier *explicitement*, c'est le
> chapitre 11 dans MySQL 5.7
> <https://dev.mysql.com/doc/refman/5.7/en/charset-applications.html>) puis à
> peupler ces tables avec des données en UTF8 depuis Perl/DBI et depuis un
> client comme MySQL-Workbench pour comparer ce qui est stocké puis finalement
> les réextraire avec Perl/DBI pour vérifier que tout marche bien.

J'avais vérifié le CHARACTER SET de la base de données par SHOW CREATE DATABASE <NomDeLaBase>, ça semblait correct.

J'ai créé un nouvel ECM en forçant le CHARACTER SET de la table temporaire.
Et cette fois je mets le résultat que j'obtiens avec cet ECM.

Reste un problème éventuel de version, du serveur MySQL notamment qui
est en 5.5, mais dès lors que les requêtes fonctionnent, cela ne
devrait pas être le bon problème.

Cordialement.

Dominique

--
-------------- section suivante --------------
Une pièce jointe autre que texte a été nettoyée...
Nom: dbi-et-utf8.pl
Type: text/x-perl
Taille: 1208 octets
Desc: non disponible
URL: <http://listes.mongueurs.net/mailman/private/perl/attachments/20160629/99adf27e/attachment.bin>
-------------- section suivante --------------
DBI VERSION: 1.631
DBD mysql VERSION: 4.028

$tempShow = {
              'temp' => 'CREATE TEMPORARY TABLE `temp` (
  `s` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8'
            };

$sInDesc = 'UTF8 on, non-ASCII, 3 characters 4 bytes';
$sOutDesc = 'UTF8 off, non-ASCII, 4 characters 4 bytes';


Plus d'informations sur la liste de diffusion Perl