IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Requêtes MySQL Discussion :

Update avec conversion de character set


Sujet :

Requêtes MySQL

  1. #1
    Pgs
    Pgs est déconnecté
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    482
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 482
    Points : 100
    Points
    100
    Par défaut Update avec conversion de character set
    Bonjour,

    Dans la requête
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    update tablecible c, tablesource s set c.champcible=s.champsource where c.id = s.id
    Le champ s.champsource est en utf8_general_ci et le champ c.champcible est en latin1_swedish_ci

    Comment faire la conversion dans l'instruction update ?

    Merci

  2. #2
    Membre émérite Avatar de vttman
    Homme Profil pro
    Développeur "couteau mosellan"
    Inscrit en
    Décembre 2002
    Messages
    1 140
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur "couteau mosellan"
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2002
    Messages : 1 140
    Points : 2 286
    Points
    2 286
    Par défaut
    A Tester ou attendre des propositions de spécialistes

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    convert(cast(convert(s.champsource using  utf8) as binary) using latin1)
    Emérite, émérite je ne pense pas ... plutôt dans le développement depuis FORT FORT longtemps, c'est mon job, ça oui
    A part ça ... Il ne pleut jamais en Moselle !

  3. #3
    Pgs
    Pgs est déconnecté
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    482
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 482
    Points : 100
    Points
    100
    Par défaut
    Merci le Mosellan !
    Ça marche parfaitement !!
    Bonne journée,

  4. #4
    Pgs
    Pgs est déconnecté
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    482
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 482
    Points : 100
    Points
    100
    Par défaut
    J'en profite pour une question.
    J'ai fait un test ; dans une table MySQL avec 3 champs (utf8, latin1 et latin1), j'ai inséré (via un select) un champ de character set utf8 "champtest" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select champtest, champtest, convert(cast(convert(champtest using  utf8) as binary) using latin1)
    Lorque je regarde avec phpMyAdmin l'enregistrement obtenu, je constate que :
    • le champ utf8 dans lequel j'ai mis de l'utf8 est bien affiché
    • le champ latin1 dans lequel j'ai mis de l'utf8 est bien affiché
    • le champ latin1 dans lequel j'ai mis du latin1 s'affiche avec des caractères spéciaux

    C'est comme si le character set défini au niveau du champ ne comptait pas, et que seul le character set des données insérées avait un impact.

    Quelqu'un peut-il m'expliquer ?

    Merci d'avance

  5. #5
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 381
    Points : 19 065
    Points
    19 065
    Par défaut
    Salut Pgs.

    Citation Envoyé par Pgs
    Le champ s.champsource est en utf8_general_ci et le champ c.champcible est en latin1_swedish_ci
    En MySql, on parle de colonne et non de champ.
    Puis, ne confondez pas charset avec collate. Le collate sert à l'interclassement, c'est-à-dire au tri (order by) des chaînes de caractères, et si vous faites une distinction entre 'e' et 'é' quand vous faites une recherche.

    Citation Envoyé par Pgs
    Comment faire la conversion dans l'instruction update ?
    Pour la conversion, lisez ceci : http://dev.mysql.com/doc/refman/5.7/...onversion.html

    Pour convertir une colonne, il suffit de faire ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ALTER TABLE `tablecible` MODIFY `chamcible` CHAR(255) CHARACTER SET `latin1` collate `latin1_general_ci`;
    Pour convertir une table, vous faites cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ALTER TABLE `tablecible` CONVERT TO CHARACTER SET `latin1` collate `latin1_general_ci`;
    Voici un exemple de conversion :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    --------------
    SET AUTOCOMMIT = 0
    --------------
     
    --------------
    START TRANSACTION
    --------------
     
    --------------
    DROP DATABASE IF EXISTS `base`
    --------------
     
    --------------
    CREATE DATABASE `base`
            DEFAULT CHARACTER SET `latin1`
            DEFAULT COLLATE       `latin1_general_ci`
    --------------
     
    --------------
    DROP TABLE IF EXISTS `test`
    --------------
     
    --------------
    CREATE TABLE `test`
    ( `id`   integer   NOT NULL AUTO_INCREMENT PRIMARY KEY,
      `ch1`  char(255)     NULL,
      `ch2`  char(255)     NULL
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    --------------
     
    --------------
    INSERT INTO `test` (`ch1`,`ch2`) VALUES
      ('Été', 'Été'), ('Forêt', 'Forêt')
    --------------
     
    --------------
    SELECT    id, ch1, length(ch1), ch2, length(ch2) FROM test
    --------------
     
    +----+-------+-------------+-------+-------------+
    | id | ch1   | length(ch1) | ch2   | length(ch2) |
    +----+-------+-------------+-------+-------------+
    |  1 | Été   |           3 | Été   |           3 |
    |  2 | Forêt |           5 | Forêt |           5 |
    +----+-------+-------------+-------+-------------+
    --------------
    SELECT    column_name, character_set_name, collation_name
        FROM  information_schema.COLUMNS
       WHERE  table_schema = 'base'
         AND  table_name   = 'test'
    ORDER BY  ordinal_position
    --------------
     
    +-------------+--------------------+-------------------+
    | column_name | character_set_name | collation_name    |
    +-------------+--------------------+-------------------+
    | id          | NULL               | NULL              |
    | ch1         | latin1             | latin1_general_ci |
    | ch2         | latin1             | latin1_general_ci |
    +-------------+--------------------+-------------------+
    --------------
    ALTER TABLE `test` MODIFY `ch2` char(255) CHARACTER SET `utf8` COLLATE `utf8_general_ci`
    --------------
     
    --------------
    SELECT    column_name, character_set_name, collation_name
        FROM  information_schema.COLUMNS
       WHERE  table_schema = 'base'
         AND  table_name   = 'test'
    ORDER BY  ordinal_position
    --------------
     
    +-------------+--------------------+-------------------+
    | column_name | character_set_name | collation_name    |
    +-------------+--------------------+-------------------+
    | id          | NULL               | NULL              |
    | ch1         | latin1             | latin1_general_ci |
    | ch2         | utf8               | utf8_general_ci   |
    +-------------+--------------------+-------------------+
    --------------
    SELECT    id, ch1, length(ch1), ch2, length(ch2) FROM test
    --------------
     
    +----+-------+-------------+-------+-------------+
    | id | ch1   | length(ch1) | ch2   | length(ch2) |
    +----+-------+-------------+-------+-------------+
    |  1 | Été   |           3 | Été   |           5 |
    |  2 | Forêt |           5 | Forêt |           6 |
    +----+-------+-------------+-------+-------------+
    --------------
    ALTER TABLE `test` CONVERT TO CHARACTER SET `utf8` COLLATE `utf8_general_ci`
    --------------
     
    --------------
    SELECT    column_name, character_set_name, collation_name
        FROM  information_schema.COLUMNS
       WHERE  table_schema = 'base'
         AND  table_name   = 'test'
    ORDER BY  ordinal_position
    --------------
     
    +-------------+--------------------+-----------------+
    | column_name | character_set_name | collation_name  |
    +-------------+--------------------+-----------------+
    | id          | NULL               | NULL            |
    | ch1         | utf8               | utf8_general_ci |
    | ch2         | utf8               | utf8_general_ci |
    +-------------+--------------------+-----------------+
    --------------
    SELECT    id, ch1, length(ch1), ch2, length(ch2) FROM test
    --------------
     
    +----+-------+-------------+-------+-------------+
    | id | ch1   | length(ch1) | ch2   | length(ch2) |
    +----+-------+-------------+-------+-------------+
    |  1 | Été   |           5 | Été   |           5 |
    |  2 | Forêt |           6 | Forêt |           6 |
    +----+-------+-------------+-------+-------------+
    --------------
    COMMIT
    --------------
     
    --------------
    SET AUTOCOMMIT = 1
    --------------
     
    Appuyez sur une touche pour continuer...
    Vous avez remarqué que la longueur des colonnes a changé.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  6. #6
    Pgs
    Pgs est déconnecté
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    482
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 482
    Points : 100
    Points
    100
    Par défaut
    Merci beaucoup pour ces informations précises.
    Philippe

  7. #7
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 381
    Points : 19 065
    Points
    19 065
    Par défaut
    Re-salut Pgs.

    Nous partons de l'exemple où nous avons pour :
    --> ch1 : character set `latin1` collate `latin1_general_ci`
    --> ch2 : character set `utf8` collate `utf8_general_ci`

    Et pour bien vérifier que la conversion s'est faite, nous affichons le caractère en hexadécimal; comme ci après :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    --------------
    SELECT    id, ch1, hex(ch1), length(ch1), ch2, hex(ch2), length(ch2) FROM test
    --------------
     
    +----+-------+------------+-------------+-------+--------------+-------------+
    | id | ch1   | hex(ch1)   | length(ch1) | ch2   | hex(ch2)     | length(ch2) |
    +----+-------+------------+-------------+-------+--------------+-------------+
    |  1 | Été   | C974E9     |           3 | Été   | C38974C3A9   |           5 |
    |  2 | Forêt | 466F72EA74 |           5 | Forêt | 466F72C3AA74 |           6 |
    +----+-------+------------+-------------+-------+--------------+-------------+
     
    Appuyez sur une touche pour continuer...
    Et là, oh miracle, les chaînes de caractères sont lisibles !

    Citation Envoyé par Pgs
    Quelqu'un peut-il m'expliquer ?
    Il y plusieurs niveaux à considérer lors de la gestion des chaînes de caractères :

    1) le contenu du script ou si vous préférez le choix du code des caractères.
    J'utilise notepad++ et j'ai comme encodage "Ansi" (c'est du windows-1252).
    Il suffit de se rendre dans l'onglet "encodage" et vous remarquerez que la ligne "Encoder en ANSI" est cochée.

    2) le stockage de la chaîne de caractères dans la base de données, dans la table ou encore dans la colonne.
    Dans mon exemple précédent, vous avez les différents exemples de déclaratives.
    Il est nécessaire de donner le charset et le collate afin que l'on sache quel codification a été utilisé lors du stockage de la chaîne de caractères dans la colonne.

    3) le transfert entre votre script et le SGBDR.
    Il s'agit de ce que les débutants ont tendance à oublier : "set names latin1" si le transfert de vos données est en latin1.
    Il s'agit de ce que vous transférez et non comment cela va être stocké.

    Dans mon exemple, le script est codifié en latin1.
    Afin que MySql sache ce que je tranfère, j'indique par un "set names latin1" le type de codification utilisé.
    Et où doit(on déclarer cela ? Dans le fichier my.ini. Voici ce que j'ai mis afin d'être en conformité avec mes résultats :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    [client]
    # --------------- #
    #     Charset     #
    # --------------- #
    
    default-character-set = latin1
    
    
    [wampmysqld]
    # --------------- #
    #     Charset     #
    # --------------- #
    
    character-set-server     = latin1
    collation-server         = latin1_general_ci
    character-set-filesystem = latin1
    
    init-connect             = 'SET NAMES latin1 COLLATE latin1_general_ci'
    4) l'affichage.
    J'utilise la console windows et de ce fait, j'affiche mes caractères en Windows-1252.
    --> https://msdn.microsoft.com/fr-fr/lib...(v=vs.85).aspx

    Dans le jargon de windows, on nomme cela "code page". On retiendra les "code page" suivants :
    --> 850 pour "OEM Multilingual Latin 1; Western European (DOS)".
    --> 1252 pour "ANSI Latin 1; Western European (Windows)"
    --> 28591 pour "ISO 8859-1 Latin 1; Western European (ISO)". C'est le "latin1" de MySql.
    --> 28605 pour "ISO 8859-15 Latin 9". C'est le latin9 de MySql.
    --> 65001 pour "Unicode (UTF-8)". C'est l'UTF-8.


    Si une déclarative manque, MySql ne saura pas comment convertir (si cela est nécessaire) la chaîne de caractères à l'affichage.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  8. #8
    Pgs
    Pgs est déconnecté
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    482
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 482
    Points : 100
    Points
    100
    Par défaut
    Merci !

    Donc si je stocke une chaîne utf8 dans une colonne latin1, elle reste utf8, c'est bien cela ?

    Et donc si je me limite à faire insert/select (sans tri et sans affichage) concernant une chaîne utf8, peu importe que la colonne soit utf8 ou latin1. C'est bien cela ?

    Philippe

  9. #9
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 381
    Points : 19 065
    Points
    19 065
    Par défaut
    Salut Pgs.

    Citation Envoyé par Pgs
    Donc si je stocke une chaîne utf8 dans une colonne latin1, elle reste utf8, c'est bien cela ?
    Non. Si dans votre script, vous gérez des caractères encodés en UTF8 et si vous précisez que le transfert va se faire aussi en UTF8, MySql s'aura comment convertir votre chaîne de caractères.
    Si dans la colonne de votre table, comme dans mon exemple, vous précisez que c'est du LATIN1, il va convertir le UTF8 en LATIN1.
    Sauf que vous pouvez rencontrer des problèmes de conversions car il y a des caractères UTF8 qui n'ont aucune correspondance en LATIN1.

    Citation Envoyé par Pgs
    si je me limite à faire insert/select (sans tri et sans affichage) concernant une chaîne utf8, peu importe que la colonne soit utf8 ou latin1. C'est bien cela ?
    Non et non. Quel est l'intérêt de se limiter à ne pas faire de tri, ni d'affichage ?
    L'intérêt d'utiliser le charset international UTF8 est de pouvoir gérer le chinois, l'arabe, et d'autres langues non latine.
    Le latin1 gère au grand maximum 255 caractères de type latin d'europe occidentale.

    La grosse difficulté dans la gestion des charset, c'est que le chemin allant de la saisie en passant par le stockage, jusqu'à l'affichage final, passe par de nombreuses étapes ou il faut préciser le charset utilisé.
    Chez moi, je travail qu'avec le charset propre à windows et qui est windows-1252.
    C'est proche du ISO_8859_15 et vu que je ne gère que le français et accessoirement l'anglais, cela répond à mes besoins.
    D'autre part, avec l'UTF8, un caractère peut occuper 1, 2 ou 3 octets, à l'inverse du charset locaux.

    Votre affirmation est fausse car dans mon exemple, avec le contenu en hexadécimal, on remarque que la codification n'est pas la même.
    Mais vu que je travaille avec la console windows, je suis limité par la police de caractères que j'utilise, entre autre le "déjà vu sans mono", qui n'affiche pas le chinois et l'arabe.
    Mais sous PhpMyAdmin, je n'ai aucun problème, même si j'utilise le code d'un caractère chinois qui s'affichera normalement.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 11
    Dernier message: 21/06/2012, 17h05
  2. Pb avec character set NLS_LANG
    Par dumb85 dans le forum Administration
    Réponses: 6
    Dernier message: 06/08/2010, 10h50
  3. Probleme de "look" avec "Use Unicode Character Set"
    Par hassenman dans le forum MFC
    Réponses: 2
    Dernier message: 13/01/2010, 11h19
  4. Réponses: 15
    Dernier message: 21/03/2006, 16h13
  5. Problème avec accents et CHARACTER SET ISO8859_1
    Par kinda dans le forum InterBase
    Réponses: 13
    Dernier message: 30/10/2003, 15h49

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo