Como faço para o imp usar o conjunto de caracteres do direito?

2

Estou tentando importar um arquivo dmp de um banco de dados para outro. O problema é que alguns caracteres dinamarqueses especiais não são importados corretamente porque algumas conversões de mapas de caracteres são feitas durante a importação.

Esta é a informação quando inicio a importação com imp (veja a nota sobre a possível conversão de caracteres):

Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

Export file created by EXPORT:V10.02.01 via conventional path

import done in WE8ISO8859P1 character set and AL16UTF16 NCHAR character set
import server uses AL32UTF8 character set (possible charset conversion)
. importing USERNAME's objects into USERNAME    
. . importing table                      "TABLE2" 
IMP-00019: row rejected due to ORACLE error 12899
IMP-00003: ORACLE error 12899 encountered
ORA-12899: værdi er for stor for kolonnen "USERNAME"."TABLE2"."NAME" (faktisk: 32, maksimum: 30)
Column 1 408261
Column 2 KUBEN FÆLLES MÅLER            

Cada caractere especial (normalmente Æ, Ø e Å) está usando 2 caracteres em vez de 1, e os dados são preenchidos com espaços para preenchimento, portanto, isso causa um erro que os dados contêm 31 caracteres para esse campo, e campo é definido como tamanho 30.

A exportação que gerou o arquivo dmp foi executada assim:

SET CHARACTERSET=WE8PC850
SET NLS_LANG=DANISH
SET NLS_NUMERIC_CHARACTERS=.,
exp username/password@server1 dumpfile.dmp

A importação foi executada assim: Como faço isso funcionar corretamente?

SET CHARACTERSET=WE8PC850
SET NLS_LANG=DANISH
SET NLS_NUMERIC_CHARACTERS=.,
imp username/password@server2 fromuser=username touser=username commit=y ignore=y file=dumpfile.dmp log=dumpfile.log

O que pode ser feito para acertar isso? Parece que o imp ignora o conjunto de caracteres usado, pois o servidor de importação usa o AL32UTF8 (que está errado).

    
por awe 30.09.2011 / 10:07

3 respostas

2

Você está importando dados para um banco de dados usando o conjunto de caracteres AL32UTF8 (este é o padrão). O importador deve, portanto, converter os caracteres para encaixar isso e alguns se tornarão caracteres de múltiplos bytes como você encontrou. Existem duas maneiras de lidar com isso:

1) Se você não precisa do Unicode no novo banco de dados, recrie-o no mesmo conjunto de caracteres que o banco de dados antigo. Execute este código no banco de dados antigo para obter o conjunto de caracteres e usar isso

SELECT parameter, value
FROM nls_database_parameters
WHERE parameter
LIKE '%CHARACTERSET';

Quando o banco de dados novo e antigo tiver o mesmo conjunto de caracteres, a importação não terá que fazer a conversão.

2) Se você puder pré-criar as tabelas, você pode usar o Parâmetro NLS_LENGTH_SEMANTICS . Se você definir isso como CHAR em vez do padrão BYTE, um VARCHAR2 (5) terá espaço suficiente para armazenar 5 caracteres no conjunto de caracteres do banco de dados (potencialmente até 20 bytes) em vez de 5 bytes (o que poderia permitir apenas 1 caractere ). Ou, em vez disso, você poderia modificar a DDL de criação de tabela para adicionar CHAR a cada declaração de coluna VARCHAR2. por exemplo,

CREATE TABLE xyz (column_x VARCHAR2(10 CHAR) NOT NULL);

Desta forma, você pode converter os dados para Unicode e ter um conjunto de caracteres melhor daqui para frente, e, desde que seu aplicativo possa suportá-lo, talvez esse seja o método preferido.

    
por 30.09.2011 / 16:02
0

se você estiver usando o oracle server XE, não é possível alterar o conjunto de caracteres do servidor de banco de dados ou de qualquer banco de dados. Eu também estou procurando por uma resposta.

    
por 17.12.2011 / 16:17
0

Acabamos resolvendo isso alterando todos os campos de caracteres para usar CHAR em vez do padrão BYTE . Esta é basicamente a opção 2 proposta por @BrokenCrust em sua resposta . Em vez de recriar as tabelas, apenas as redefinimos usando este SQL:

set head off;
set linesize 1000;
set colsep ";";
set trimspool on;
set pagesize 0;
set verify off;
set feedback off;
set term off;
column dcol new_value mydate noprint;
select to_char(sysdate,'YYYY-MM-DD_HH24MISS') dcol from dual;
select to_char(sysdate,'YYYY-MM-DD') dcol from dual;
spool c:\temp\From_Byte_to_Char_og_VarChar2&mydate;
select '-- '||sysdate from dual;
select 'ALTER TABLE '||TABLE_NAME||
      ' MODIFY '||COLUMN_NAME||' CHAR('||data_length||' CHAR);' 
from 
     user_tab_cols
where 
     DATA_TYPE='CHAR'
;
select 'ALTER TABLE '||TABLE_NAME||
      ' MODIFY '||COLUMN_NAME||' VARCHAR2('||data_length||' CHAR);' 
from 
     user_tab_cols
where 
     DATA_TYPE='VARCHAR2'
;
select 'commit ;' from dual;
select 'exit ;' from dual;
spool off ;
    
por 23.01.2012 / 08:07