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

PL/SQL Oracle Discussion :

Utl_File : lire data en UTF8 et écrire en WE8MSWIN1252 [11g]


Sujet :

PL/SQL Oracle

  1. #1
    Membre à l'essai
    Inscrit en
    Mai 2009
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Mai 2009
    Messages : 18
    Points : 18
    Points
    18
    Par défaut Utl_File : lire data en UTF8 et écrire en WE8MSWIN1252
    Bonjour
    J'ai une procédure qui génère un fichier à partir de la lecture d'infos en base. Cette procédure fonctionne bien en v10, mais en V11 (encodage de la base en UTF8), le résulat n'est plus bon et les cacratères accentués sont altérés.
    Les informations sont stockées de la manière suivantes :
    - NVARCHAR pour la base v11
    - VARCHAR pour la V10

    La proc (simplifiée donne ceci) :
    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
     
    CREATE OR REPLACE PROCEDURE test_convert
    IS
    	FileName 	VARCHAR2( 100) ;
    	exp_fichier	UTL_FILE.FILE_TYPE;
    	ligne		VARCHAR2(2000) ;
    	dmp		VARCHAR2(2000) ;
    BEGIN
    	FileName := 'test_convert.txt' ;
    	exp_fichier := UTL_FILE.FOPEN( 'EXPORT_CODE', FileName, 'w' );
     
    -- résultat attendu     élève : Typ=1 Len=5: e9,6c,e8,76,65
     
    	SELECT	CONVERT( NOM,'WE8MSWIN1252'),
    		DUMP(CONVERT( NOM,'WE8MSWIN1252'), 16)
    	INTO	ligne,
    		dmp
    	FROM	clients
    	WHERE	reference = 1917505 ;
     
    	UTL_FILE.PUT_LINE(exp_fichier, 'Value : ' || ligne );
    	UTL_FILE.PUT_LINE(exp_fichier, 'Dump  : ' || dmp );
     
     
    	-- Vidage du tampon et fermeture du fichier
    	UTL_FILE.FFLUSH(exp_fichier);
    	UTL_FILE.FCLOSE(exp_fichier);
     
    END ;
    /
    SHOW ERR
     
    execute test_convert
    Le résultat donne alors : il y a juste 2 carrés après le mot "value :"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Value : 
    Dump  : Typ=1 Len=5: bf,6c,bf,76,65
    Alors que le code de la même procédure en oracle V10 (dans laquelle je n'utilise pas la fonction Convert) donnait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Value : élève
    Dump  : Typ=1 Len=5: e9,6c,e8,76,65
    On voir nettement une différence sur les valeurs des caratères accentués
    J'ai essayé tout un tas de conversion (ci-dessous : convert utilisé et dump affiché, certains tests sont idiots, mais je voulais juste voir ce que cela donnait, se sont les "convert" 1 et 5 qui m'interessent ) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    CONVERT( nom, 'WE8MSWIN1252')             ==> Typ=1 Len=5: bf,6c,bf,76,65
    CONVERT( nom, 'AL16UTF16')                ==> Typ=1 Len=10: 0,82,0,6c,0,8a,0,76,0,65
    CONVERT( nom, 'UTF8')                     ==> Typ=1 Len=7: c2,82,6c,c2,8a,76,65
    CONVERT( nom, 'WE8ISO8859P15')            ==> Typ=1 Len=5: 82,6c,8a,76,65
    CONVERT( nom, 'WE8MSWIN1252', 'AL32UTF8') ==> Typ=1 Len=10: 0,bf,0,6c,0,bf,0,76,0,65
    CONVERT( nom, 'AL16UTF16', 'AL32UTF8')    ==> Typ=1 Len=20: 0,0,ff,fd,0,0,0,6c,0,0,ff,fd,0,0,0,76,0,0,0,65
    CONVERT( nom, 'UTF8', 'AL32UTF8')         ==> Typ=1 Len=14: 0,ef,bf,bd,0,6c,0,ef,bf,bd,0,76,0,65
    CONVERT( nom, 'WE8ISO8859P15', 'AL32UTF8')==> Typ=1 Len=10: 0,bf,0,6c,0,bf,0,76,0,65
    CONVERT( nom, 'US7ASCII')                 ==> Typ=1 Len=5: 3f,6c,3f,76,65
    Informations sur les bases
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    param de la base en v10 : (pas d encodage particuliers, que je sache)
      NLS_CHARACTERSET           WE8ISO8859P15
      NLS_NCHAR_CHARACTERSET     AL16UTF16
    param de la base en v11 (encodage en UTF8)
      NLS_CHARACTERSET           AL32UTF8
      NLS_NCHAR_CHARACTERSET     AL16UTF16
    aucune n'est satisfaisante
    si vous avez un idée, je suis preneur
    Merci

  2. #2
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Je n'ai pas de base encodée en UTF8 à disposition pour faire des tests mais déjà qu'est-ce que ça donne si vous supprimez la fonction convert et écrivez directement le contenu de la variable ligne ? Limitez-vous à la valeur élève, combien d'octets a le fichier ainsi obtenu et quel est son contenu ?

  3. #3
    Membre à l'essai
    Inscrit en
    Mai 2009
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Mai 2009
    Messages : 18
    Points : 18
    Points
    18
    Par défaut
    Bonjour

    La procédure initiale n'utilisait pas la fonction convert, puisque on était pas dans un encodage particulier, et les fichiers produit était corrects

    Le nouveau contexte d'exécution est le suivant.
    Données enregistrées dans des NVARCHAR2 dans une base encodée UTF (voir post précédent).
    La sortie doit se faire dans des fichiers en WE8MSWIN1252.

    Pour ce qui est du contenu obtenu, c'est ce qui est décrit dans les deux zones "CODE"

    Petite précision sur le test décrit ci-dessus, les données ont été mises à jour à partir de SqlPlus sous DOS (ça peut faire varier le résultat)
    Je suis en train de refaire des tests avec le loader oracle sur une console unix, .. pour le moment, ca n'a pas l'air d'aller mieux...

  4. #4
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Inutile de répéter ce que vous avez déjà dit. Essayez d'utiliser la fonction convert du package UTL_RAW
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Select 
              utl_raw.convert
              (
                 utl_raw.cast_to_raw(b),
                 'AMERICAN_AMERICA.WE8MSWIN1252',   -- To character set.
                 'AMERICAN_AMERICA.AL16UTF16'        -- From Character set.
              )
      from t_ch
    Mais vu le paragraphe suivant de la documentation d'Oracle je me demande si vous ne devez pas écrire dans votre fichier en binaire.
    UTL_FILE expects that files opened by UTL_FILE.FOPEN in text mode are encoded in the database character set. It expects that files opened by UTL_FILE.FOPEN_NCHAR in text mode are encoded in the UTF8 character set. If an opened file is not encoded in the expected character set, the result of an attempt to read the file is indeterminate. When data encoded in one character set is read and Globalization Support is told (such as by means of NLS_LANG) that it is encoded in another character set, the result is indeterminate. If NLS_LANG is set, it should therefore be the same as the database character set.

  5. #5
    Membre à l'essai
    Inscrit en
    Mai 2009
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Mai 2009
    Messages : 18
    Points : 18
    Points
    18
    Par défaut
    Excellente suggestion
    merci

    Ca fonctionne correctement, et surtout le format du fichier est correct. Il me reste juste à mettre les encodages en paramètre (comme ça, on sera tranquille)

    Pour information, la fonction convert fonctionne bien, mais produit quand même des caractères utf, aussi, en jouant avec le CharacterSet en entrée (sqlldr), je n'avais même plus besoin de convertir. Ceci a eu pour résultat de produire un fichier lisible.
    Mais allant plus loin et en regardant l'encodage des caractères, on était quand même en utf (ce qui s'explique car la base a été construite en utf).

    La solution avec le type Raw et la conversion que tu m'as proposée résoud ce problème.

    Encore merci

    je déclare le sujet résolu !

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

Discussions similaires

  1. [XE5] Lire data d'un COM sur Mac OS X
    Par shadow578 dans le forum Composants FMX
    Réponses: 0
    Dernier message: 26/06/2014, 11h47
  2. Lire un fichier text et écrire dans une table oracle
    Par naima2005 dans le forum VB.NET
    Réponses: 6
    Dernier message: 28/12/2007, 11h35
  3. lire de la base et écrire dans un fichier .doc
    Par atef83 dans le forum Administration
    Réponses: 1
    Dernier message: 18/05/2007, 01h29
  4. Réponses: 1
    Dernier message: 24/11/2004, 16h54
  5. Un langage pour lire, traiter et écrire de gros fichiers
    Par March' dans le forum Langages de programmation
    Réponses: 19
    Dernier message: 07/04/2003, 15h26

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