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

Oracle Discussion :

Export / Import : ISO --> UTF


Sujet :

Oracle

  1. #1
    Nouveau membre du Club
    Inscrit en
    Mars 2004
    Messages
    51
    Détails du profil
    Informations forums :
    Inscription : Mars 2004
    Messages : 51
    Points : 34
    Points
    34
    Par défaut Export / Import : ISO --> UTF
    Oracle 9.2.0.6
    IBM AIX 5L
    Bonjour

    je dois exporter un shéma d'une base (NLS_LANG=WE8ISO8859P1)
    à une autre base (NLS_LANG=UTF8)
    Est ce que c'est possible sans avoir des conversions

    Merci

  2. #2
    Membre expert
    Avatar de LeoAnderson
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    2 938
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 2 938
    Points : 3 199
    Points
    3 199
    Par défaut
    de ISO -> UTF, oui, c'est possible, il vous suffit de bien positionner vos variables NLS_LANG avant d'appeller exp puis imp.

    Cependant, attention, cette migration peut avoir des impacts non négligeables !
    Prenons par exemple colonne définie en VARCHAR2(5);
    Par défaut (variable NLS_LENGTH_SEMANTICS), cela signifie 5 octets (ce qui, dans le cas de l'iso correspond à 5 caractères).
    par contre, cette table sera re-créée à l'identique dans la base UTF. elle sera donc définie en 5 octets.
    Or, en UTF, les caractères accentués, exotiques... prennent plus de 1 octet.
    Ainsi, la chaine "télé." prend 5 caractères, 5 octets en ISO mais 8 octets en UTF.
    Donc la colonne VARCHAR2(5) qui contient "Télé." ne pourra pas être migrée.

    Etant donné que la création des tables se fait à l'identique, jouer avec le NLS_LENGTH_SEMANTICS n'aura pas d'effet.

    Remarque : le phénomène décrit ci-dessus s'applique également aux blocs PL/SQL ! ;-)

  3. #3
    Nouveau membre du Club
    Inscrit en
    Mars 2004
    Messages
    51
    Détails du profil
    Informations forums :
    Inscription : Mars 2004
    Messages : 51
    Points : 34
    Points
    34
    Par défaut
    leoAndersen

    Merci de votre réponse , exactement j'ai eu le problème de colonne petite

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    IMP-00019: row rejected due to ORACLE error 1401
    IMP-00003: ORACLE error 1401 encountered
    ORA-01401: inserted value too large for column
    Est que vous avez une résolution pratique de ce problème

    Merci

  4. #4
    Membre expert
    Avatar de LeoAnderson
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    2 938
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 2 938
    Points : 3 199
    Points
    3 199
    Par défaut
    Non, la seule solution est de redimensionner la colonne en VARCHAR2(x CHAR) mais attention, cela pourra avoir des effets de bord... (la taille de la colonne étant changée).

    Si, par exemple, vous avez du code PL/SQL qui se base sur cette colonne mais sans spécifier %TYPE, là aussi, il faudra reporter la modification !

    De toute façon, dans ce cas, l'import devra se faire en plusieurs étapes :
    1. Import de la structure uniquement (ROWS=N)
    2. Modification des colonnes à problèmes
    3. Importation des données (IGNORE=Y, ROWS=Y)

  5. #5
    Nouveau membre du Club
    Inscrit en
    Mars 2004
    Messages
    51
    Détails du profil
    Informations forums :
    Inscription : Mars 2004
    Messages : 51
    Points : 34
    Points
    34
    Par défaut
    J'ai trouvé la solution sur metalink
    note 313175.1

    1 - il faut faire l'export
    2 - Importer tout sans les données
    3 - jouer le script
    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
     
    set feedback off
    set verify off
    set serveroutput on
    set termout on
    exec dbms_output.put_line('Starting build select of columns to be altered');
    drop table semantics$
    /
    create table semantics$(s_owner varchar2(40), 
                           s_table_name varchar2(40), 
                           s_column_name varchar2(40),
                           s_data_type varchar2(40),
                           s_char_length number)
    /
    insert into semantics$ 
      select C.owner, C.table_name, C.column_name, C.data_type, C.char_length
        from all_tab_columns C, all_tables T 
       where C.owner = T.owner
         and T.owner not in ('SYS', 'SYSTEM', 'CTXSYS', 'DBSNMP', 'DMSYS', 
                             'EXFSYS', 'HR', 'IX', 'MDSYS', 'OE', 'OLAPSYS', 
                             'ORDSYS', 'OUTLN', 'SH', 'SYSMAN', 'WKSYS', 
                             'WK_TEST', 'WMSYS', 'XDB')
         and C.table_name = T.table_name
         and C.table_name not in (select table_name from all_external_tables)
         and C.data_type in ('VARCHAR2', 'CHAR')
      -- You can exclude or include tables or schemas as you wish, by adjusting
      -- "and T.owner not in" as per your requirements
    /
    commit
    /
    declare
      cursor c1 is select * from semantics$;
      v_statement varchar2(255);
      v_nc number(10);
      v_nt number(10);
    begin
      execute immediate 
        'select count(*) from semantics$' into v_nc;
      execute immediate 
        'select count(distinct s_table_name) from semantics$' into v_nt;
      dbms_output.put_line
        ('ALTERing ' || v_nc || ' columns in ' || v_nt || ' tables');
      for r1 in c1 loop
        v_statement := 'ALTER TABLE ' || r1.s_owner || '.' || r1.s_table_name;
        v_statement := v_statement || ' modify (' || r1.s_column_name || ' ';
        v_statement := v_statement || r1.s_data_type || '(' || r1.s_char_length;
        v_statement := v_statement || ' CHAR))';
        execute immediate v_statement;
      end loop;
      dbms_output.put_line('Done');
    end;
    /
    et après importer les données

    Merci

  6. #6
    Membre expert
    Avatar de LeoAnderson
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    2 938
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 2 938
    Points : 3 199
    Points
    3 199
    Par défaut
    C'est celà.
    sauf que ce script va modifier toutes les tables applicatives et toutes les colonnes, ce qui n'est peut-être pas nécessaire...

  7. #7
    Rédacteur

    Homme Profil pro
    Consultant / formateur Oracle et SQL Server
    Inscrit en
    Décembre 2002
    Messages
    3 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant / formateur Oracle et SQL Server

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 461
    Points : 8 079
    Points
    8 079
    Par défaut
    Citation Envoyé par LeoAnderson
    Etant donné que la création des tables se fait à l'identique, jouer avec le NLS_LENGTH_SEMANTICS n'aura pas d'effet.
    Exact, je l'ai constaté à mes dépens pas plus tard que jeudi, et j'aurais été bien heureux de lire ça à ce moment-là !

    Concrètement, je suis tombé sur les erreurs suivantes lors de l'import :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    IMP-00019: row rejected due to ORACLE error 1401
    IMP-00003: ORACLE error 1401 encountered
    ORA-01401: inserted value too large for column
    La solution recommandée par Oracle (et trouvée aussi sur le site de Tom Kyte) consiste à agrandir les colonnes devenues trop étroites. Bien évidemment, on ne peut pas se le permettre quand il s'agit d'une application de production.

    Pour ma part, je m'en suis sorti en important d'abord la structure (ROWS=NO), puis en modifiant les VARCHAR2(n) en VARCHAR2(n CHAR).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    select 'alter table ' || table_name || ' modify ' || column_name || ' VARCHAR2(' || DATA_LENGTH || ' CHAR);' 
    from user_tab_columns 
    where data_type='VARCHAR2'
    and table_name in (select table_name from user_tables);
    Ensuite, import des données proprement dites, et tout s'est bien passé.


    Edit après lecture de ce qui précède : eh mince, j'avais pas vu cette note, et j'ai dû en plus réinventer la roue (pas trop complexe heureusement) !

  8. #8
    Membre expert
    Avatar de LeoAnderson
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    2 938
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 2 938
    Points : 3 199
    Points
    3 199
    Par défaut
    Citation Envoyé par Pomalaix
    (...)
    La solution recommandée par Oracle (et trouvée aussi sur le site de Tom Kyte) consiste à agrandir les colonnes devenues trop étroites. Bien évidemment, on ne peut pas se le permettre quand il s'agit d'une application de production.

    Pour ma part, je m'en suis sorti en important d'abord la structure (ROWS=NO), puis en modifiant les VARCHAR2(n) en VARCHAR2(n CHAR).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    select 'alter table ' || table_name || ' modify ' || column_name || ' VARCHAR2(' || DATA_LENGTH || ' CHAR);' 
    from user_tab_columns 
    where data_type='VARCHAR2'
    and table_name in (select table_name from user_tables);
    Ensuite, import des données proprement dites, et tout s'est bien passé.
    En même temps, techniquement, tu as quand même aggrandi la taille de tes colonnes....

    En fait, je pense (mais non testé) qu'il n'y aurait (preque) aucun problème si, dans la base ISO, le NLS_LENGTH_SEMANTICS valait CHAR et non BYTE (valeur par défaut).
    Dans ce cas, en ISO, les colonnes seraient définies en "x caractères" et donc re-créées ainsi ;-)

  9. #9
    Membre éprouvé
    Avatar de yolepro
    Profil pro
    Architecte de système d'information
    Inscrit en
    Mai 2002
    Messages
    918
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Mai 2002
    Messages : 918
    Points : 1 144
    Points
    1 144
    Par défaut
    Bonjour je remonte le problème car il m'est posé maintenant.

    J'ai une application Java qui fait des insert dans Oracle.

    Nous utilisons des VARCHAR2(4000) et nous cherchons a migrer la base en UTF-8 et qu'il soit toujours possible de mettre 4000 caractères au sens java (semantic?) dans la base.

    Je ne sais vraiment pas quelle démarche suivre? Pourtant ca devrait être quelque chose de basique comme demande non?

    Comment faire pour qu'en UTF-8 un caractere soit un caractere au sens large.

    Merci.

    PS : J'ai trouvé cette doc très interessante, mais je ne sais pas la mettre en oeuvre... ni de retour d'experience :
    [FONT=Helv]http://www.oracle.com/technology/oramag/oracle/03-mar/o23sql.html
    [/FONT]

  10. #10
    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
    Points : 3 597
    Points
    3 597
    Par défaut
    Vous devriez plutôt ouvrir une nouvelle discussion (celle-ci est marquée résolue).

    Précisez aussi votre question:
    - quel est le jeu de caractères utilisé par Oracle pour votre base actuelle ?
    - donnez-nous la résultat de le requête suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT * FROM nls_database_parameters;
    Notez aussi que le changement du jeu de caractères d'une base de données est une tâche qui concerne plus l'administration de base (modèle physique et configuration de la base) que le code applicatif qui utilise la base.

  11. #11
    Membre expert
    Avatar de LeoAnderson
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    2 938
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 2 938
    Points : 3 199
    Points
    3 199
    Par défaut
    Là, vous avez atteint les limites du problèmes....

    Je pense que VARCHAR2(4000 CHAR) soit possible lors de la définition, mais je crains que vous ne rencontriez une erreur si vous inséré 4000x le caractère "é" (je n'ai pas de bases UTF sous la main pour tester).
    En même temps, parsez vos données avec un appel à CONVERT et DUMP pour voir lequelles prendraient plus de 4000 caractères... il doit pas y en avoir des masses... ;-)

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

Discussions similaires

  1. [INFO GENERAL] Export/Import
    Par ElDadou38 dans le forum Oracle
    Réponses: 4
    Dernier message: 19/08/2005, 10h35
  2. Comment exporter / importer une table postgres
    Par Elois dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 01/03/2005, 18h22
  3. [Export-import] Comment faire ?
    Par phil_ma dans le forum Eclipse Java
    Réponses: 4
    Dernier message: 06/02/2005, 18h15
  4. Export / Imports de Bases
    Par Guizz dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 21/07/2003, 14h18
  5. Export/import des logins et pwd
    Par Colargole dans le forum MS SQL Server
    Réponses: 14
    Dernier message: 17/07/2003, 16h07

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