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

Administration Oracle Discussion :

Convertion implicite utf8 de la part d'Oracle ?


Sujet :

Administration Oracle

  1. #1
    Membre éprouvé
    Avatar de Rakken
    Homme Profil pro
    Inscrit en
    Août 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 257
    Par défaut Convertion implicite utf8 de la part d'Oracle ?
    Bonjour,

    J'ai des soucis de convertion utf8...
    Alors en gros, j'ai un fichier xml qui est stocké en utf8. Je veux lire ce fichier pour rentrer son contenu dans ma base oracle.
    Au moment de la lecture, je log ce que je fait.
    Pour chaque ligne, je fait un log avec le contenu direct, un avec le contenu ou j'ai fait un utf8_decode et un autre ou j'ai fait 2 utf8 décode, ce qui me donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    XmlToBase : de base       : content=Il doit y avoir au moins 2 أ©lأ©ments pour pouvoir les ordonner.
    XmlToBase : 1 utf8 décode : content=Il doit y avoir au moins 2 éléments pour pouvoir les ordonner.
    XmlToBase : 2 utf8 décode : content=Il doit y avoir au moins 2 ?ments pour pouvoir les ordonner.
    (la premiere ligne a ici été convertie en html, mais en vrai, j'ai des caractères zarb, genre un pipe avec un chapeau, et un ptit c de copyright).
    Mon log a été lu en "windows 1256" (Allez savoir ce que ca veut dire...) depuis jedit.

    Donc, naturellement, j'ai enregistré dans ma table avec un utf8_decode.

    Par contre, quand je liste ma table sous sqlplus (j''y accede depuis un putty) pas moyen de voir un accent... tout est foireux, et quand je fait un affichage en ligne (sous mozilla ou ie) j'ai également des caractères foireux.
    J'ai essayer de mettre ma base en UTF8, en WE8ISO8859P15 et en WE8MSWIN1252 mais rien n'y fait...

    Est-ce que Oracle fait des conversions implicite zarb ?
    Quelqu'un s'y connaissant un peu mieux que moi en jeu de caractère peut-il me dire dans quel caracter set je dois mettre ma base pour ne plus avoir ces saletées de caractère zarb ?

    Dans l'idéal, j'aimerai enregistrer sans avoir a faire de utf8_decode (jusqu'ici le code tournait sous mysql, sans faire de utf8 décode et il n'y avait pas de soucis. Les pages s'affichent en utf8 également).

    Merci d'avance pour toutes vos pistes, j'commence a être completement paumé et je ne sais plus trop quoi tester...

    --
    Rakken

  2. #2
    Membre Expert

    Profil pro
    Inscrit en
    Février 2006
    Messages
    3 437
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 3 437
    Par défaut
    Attention, si vous changez le jeu de caractères avec ALTER DATABASE sans utiliser l'outil CSSCAN pour vérifier s'il y a problème lors de la conversion il y a risque de perte de données.

    Pour bien comprendre ce qui se passe entre le jeu de caractères de la base de données et la variable NLS_LANG définie côté client, il faut étudier ça: http://fadace.developpez.com/oracle/nls/

    Essayez de faire des tests avec sqlplus et différentes valeurs pour NLS_LANG.
    Si on a un doute sur ce qui est réellement stocké dans la base, ilf aut utiliser
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT dump(<colonne>) FROM <table>
    qui affiche les octets utilisés pour stocker tout type de donnée et donc les CHAR, VARCHAR2.

  3. #3
    Membre éprouvé
    Avatar de Rakken
    Homme Profil pro
    Inscrit en
    Août 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 257
    Par défaut
    En lancant ta commande, j'obtiens une erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    describe f_locale;
     
     ID NOT NULL CHAR(255)
     LANG NOT NULL CHAR(2) 
     CONTENT CLOB
     PACKAGE VARCHAR2(255) 
     OVERRIDDEN NUMBER(10)
     
    select dump(CONTENT) from f_locale;
     
    select dump(CONTENT) from f_locale
                *
    ERREUR à la ligne 1 :
    ORA-00932: types de données incohérents : - attendu ; CLOB obtenu
    C'est le champ "content" qui contient mes données qui sont mal convertie. Par contre la commande :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select dump(LANG) from f_locale;
    Passe sans problème et me donne un résultat du genre
    Je suis de plus en plus perdu... Entre SqlPlus Worksheet, la requete php envoyé tirée d'un xml en utf8, potentiellement décodé avant l'envoie, l'affichage en utf8, l'unix sur lequel est installée la base (je code et j'affiche mes pages sous windows), je ne sais plus qui doit avoir quoi...

    --
    Rakken, qui s'accroche a ses rames et tente de souker ferme...

  4. #4
    Membre Expert

    Profil pro
    Inscrit en
    Février 2006
    Messages
    3 437
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 3 437
    Par défaut ajout précision Windows
    En effet, avec un CLOB il faut extraire une partie du CLOB avec DBMS_LOB.SUBSTR.

    Exemple:
    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
     
    SQL> create table tc (c clob);
     
    Table created.
     
     
    SQL> select dump(dbms_lob.substr(c, 10, 1)) from tc;
     
    no rows selected
     
    SQL> insert into tc values('12345');
     
    1 row created.
     
    SQL> commit;
     
    Commit complete.
     
    SQL> select dump(dbms_lob.substr(c, 10, 1)) from tc;
     
    DUMP(DBMS_LOB.SUBSTR(C,10,1))
    -------------------------------------------------------------------------------
     
    Typ=1 Len=5: 49,50,51,52,53
     
    SQL> select dump(dbms_lob.substr(c, 4, 1)) from tc;
     
    DUMP(DBMS_LOB.SUBSTR(C,4,1))
    -------------------------------------------------------------------------------
     
    Typ=1 Len=4: 49,50,51,52
    Attention, l'ordre des paramètres de DBMS_LOB.SUBSTR n'est pas le même que SUBSTR


    Pour y voir plus clair, faites d'abord des tests avec un VARCHAR2 en dehors de votre application avec sqlplus pour d'abord vous assurer que:
    1. la combinaison jeu de caractères au niveau base + NLS_LANG fonctionne côté Unix
    2. trouver le bon NLS_LANG qui fonctionne avec PHP et le navigateur
    (le jeu de caractère sera très probablement différent parce que c'est Windows)
    3. ensuite seulement, faites les tests avec le CLOB.

  5. #5
    Membre éprouvé
    Avatar de Rakken
    Homme Profil pro
    Inscrit en
    Août 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 257
    Par défaut
    Bon, après toute une série de test voila ce que j'ai.

    • Oracle : base en utf8 (c'est ce qui est visé, donc c'est cool).
    • Insert avec SQLPlusWorksheet : Client en utf8, pas de soucis pour inserer et afficher.
    • Insert avec putty : Si je configure putty en utf8, pas de soucis pour inserer et afficher, si je le mets en latin, ca foire.
    • Insert avec php : ca foire systématiquement, la lecture est ok.

    La requete de tests était la même dans chacun des cas, avec une table de tests contenant seulement un varchar2, histoire de ne pas avoir de parasite.

    D'ou ma super question, comment je fait pour que la requête passe bien depuis php ?
    J'ai essayé de faire des utf8 encode et decode dans tous les sens, je n'ai trouvé aucune combinaison qui soit capable d'exectuer correctement ma requete...

    Y-a-y il un parametre caché ? Un truc ?

    --
    Rakken, qui ne comprend définitivement pas...

  6. #6
    Membre Expert

    Profil pro
    Inscrit en
    Février 2006
    Messages
    3 437
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 3 437
    Par défaut
    Il faut vérifier que la valeur de NLS_LANG définie au moment du démarrage du serveur web qui exécute le code PHP est la bonne valeur.

    NLS_LANG est une variable d'environnement (et peut aussi être une clé de registre sous Windows) toujours définie au niveau OS, jamais dans Oracle
    dans le init.ora ou par ALTER SESSION. Dans la cas d'un processus qui tourne en tâche de fond, c'est la valeur définie au moment du démarrage de ce processus qui est prise en compte. Ici le processus, c'est le serveur web et c'est bien lui qui est le client Oracle.

  7. #7
    Membre éprouvé
    Avatar de Rakken
    Homme Profil pro
    Inscrit en
    Août 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 257
    Par défaut
    Bon j'ai défini NLS_LANG sur la machine qui heberge apache (et je n'ai pas oublié de redémarer apache ^^).

    Maintenant dans php, si je fait un :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo "Variable d'environement : " . getenv("NLS_LANG") . "<br />";
    Ca m'affiche :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Variable d'environement : american_america.utf8
    Ce qui est la même valeur que ce que j'ai sur mon serveur oracle, ce qui, a priori correspond également aux parametres de langues qui sont spécifié dans oracle.

    Normalement ca devrait fonctionner la !

    C'est pas la bonne valeur que j'ai renseigné ? J'ai loupé un truc ?
    --
    Rakken

  8. #8
    Membre éprouvé
    Avatar de Rakken
    Homme Profil pro
    Inscrit en
    Août 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 257
    Par défaut
    Petite précision sur les tests en cours...
    Ce que je voudrai voir afficher c'est:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    "Valeur depuis xxx : onié a"
    J'ai fait une table qui contient seulement un champ (un varchar2). J'ai faits des insertions dans cette tables depuis differents environements.

    Lorsque j'affiche le contenu de ma page depuis une page web :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Variable d'environement : american_america.utf8
     
    Committed
     
    ----selecting
    [Valeur depuis putty iso : oni? a]
    [Valeur depuis putty UTF8 : onie a]
    [Valeur avec un utf8 encode : oni?? a]
    [Valeur avec un utf8 decode : oni? a]
    [Valeur avec deux utf8_decode : oni? a]
    [Valeur avec deux utf8_encode : oni???? a]
    [Valeur depuis sqlplusWorksheet : onie a]
    ----done
    Le contenu de ma table lorsque j'affiche depuis putty :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    SQL> select * from onitest;
     
    TESTF
    ----------------------------------------------------------------
    Valeur depuis putty iso : oni▒   a
    Valeur depuis putty UTF8 : onié   a
    Valeur avec un utf8 encode : oni��   a
    Valeur avec un utf8 decode : oni? a
    Valeur avec deux utf8_decode : oni? a
    Valeur avec deux utf8_encode : oni����   a
    Valeur depuis sqlplusWorksheet : onié   a
     
    7 rows selected.
    (A noter que sous mon putty ca n'est pas des codes qui s'affichent mais bel et bien des caractères étranges, du genre point d'interogation sur fond de losange noir.

    Et pour finir, ce qui est affiché depuis sqlplusWorksheet :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    TESTF
    ----------------------------------------------------------------
    Valeur depuis putty iso : oni¿ a
    Valeur depuis putty UTF8 : onié   a
    Valeur avec un utf8 encode : oni¿¿   a
    Valeur avec un utf8 decode : oni? a
    Valeur avec deux utf8_decode : oni? a
    Valeur avec deux utf8_encode : oni¿¿¿¿   a
    Valeur depuis sqlplusWorksheet : onié   a
     
    7 ligne(s) sélectionnée(s).
    La seule maniere de "voir" mon accents, c'est lorsque j'insere depuis putty en utf8 ou sqlplusWorksheet ET que je lit depuis putty utf8 ou sqlplusWorksheet...

    --
    Rakken, je trouverai, oh oui, un jour, je trouverai...

  9. #9
    Membre Expert

    Profil pro
    Inscrit en
    Février 2006
    Messages
    3 437
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 3 437
    Par défaut
    Ce n'est pas forcément une bonne idée d'assigner à NLS_LANG pour le jeu de caractères de la base la même valeur que celui de la base. Car il faut aussi être sûr que l'environnement client en fait l'OS sait afficher directement le jeu de caractères en question, avec UTF8, on peut avoir des doutes. Et il y risque de "corruption" des données car Oracle ne vérifie plus aucune donnée caractère .

    En général pour des données "occidentales" sous Unix on choisit un WE8ISO8859* et sous Windows WE8MSWIN1252.

  10. #10
    Membre éprouvé
    Avatar de Rakken
    Homme Profil pro
    Inscrit en
    Août 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 257
    Par défaut
    Le problème, c'est que je n'ai pas necessairement que des données occidentale.
    Il y a certain champ qui sont traduit en arabe.

    Ceci mis a part, si on résume :
    Mon serveur apache prend WE8ISO8859 (il tourne sous unix)
    Mon serveur oracle prend également WE8ISO8859 (Sous unix également)
    Oracle reste configuré avec UTF8 ?

    Hummm
    Je doute fort que ce soit ca la bonne combinaison...

    Si ?

    --
    Rakken

  11. #11
    Membre Expert

    Profil pro
    Inscrit en
    Février 2006
    Messages
    3 437
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 3 437
    Par défaut
    Afficher des caractères latins et arabes doit être possible avec les jeux suivantshttp://download-uk.oracle.com/docs/c...ppa.htm#968651 (mais je n'ai jamais rien testé dans ce domaine là, l'arabe pour moi c'est du chinois ).

    Et voir ce que dit Oracle à propos du choix du jeu client par rapport au jeu serveur:
    http://download-uk.oracle.com/docs/c.../ch3.htm#56353

  12. #12
    Membre éprouvé
    Avatar de Rakken
    Homme Profil pro
    Inscrit en
    Août 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 257
    Par défaut
    Victoiiiiiiiiiiiiiiiiiiiiiiiire !

    Alors après avoir crée des variables d'environement dans tous les sens, avoir changé leurs valeurs un nombre impressionnant de fois, finalement, LA solution.

    Au moment de l'appel a oci_connect() en php, il y a un parametre optionnel, qui est "charset", et qu'il faut mettre a utf8.

    Déprimant de simplicité .

    Au final, ma configuration :
    • Serveur oracle : utf8,
    • Serveur apache : utf8,
    • Affichage des pages : utf8,
    • encodage des fichiers sources : utf8,
    • création de la connection a oracle : utf8.


    Utf8 full powered, et ca roule ;-)

    Merci !!!

    --
    Rakken

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

Discussions similaires

  1. Réponses: 15
    Dernier message: 07/06/2011, 23h42
  2. Convertion mauvais UTF8 vers UTF8 valide
    Par FMaz dans le forum Requêtes
    Réponses: 0
    Dernier message: 25/11/2009, 19h24
  3. UTF-8 convertion implicite.
    Par echantillon dans le forum C
    Réponses: 10
    Dernier message: 04/02/2007, 07h36
  4. Migration Oracle 8i WE8DEC => Oracle 9i UTF8
    Par stawen dans le forum Oracle
    Réponses: 3
    Dernier message: 06/01/2005, 11h44
  5. Réponses: 2
    Dernier message: 23/06/2004, 17h06

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