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
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
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 ! ;-)
leoAndersen
Merci de votre réponse , exactement j'ai eu le problème de colonne petite
Est que vous avez une résolution pratique de ce problème
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
Merci
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 :
- Import de la structure uniquement (ROWS=N)
- Modification des colonnes à problèmes
- Importation des données (IGNORE=Y, ROWS=Y)
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
et après importer les données
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; /
Merci
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...
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à !Envoyé par LeoAnderson
Concrètement, je suis tombé sur les erreurs suivantes lors de l'import :
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.
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
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).
Ensuite, import des données proprement dites, et tout s'est bien passé.
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);
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) !
En même temps, techniquement, tu as quand même aggrandi la taille de tes colonnes....Envoyé par Pomalaix
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 ;-)
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]
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:
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.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 SELECT * FROM nls_database_parameters;
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... ;-)
Partager