Por que Char (1) mudança para Char (3) ao copiar mais de um Oracle DBLINK?
Pergunta
I têm bases de dados 2, e
Base de Dados A é Oracle 9i, tem que codifica WE8ISO8859P1, e contém uma tabela "foo" com pelo menos uma coluna de tipo CHAR (1 carvão animal). Eu não posso mudar a tabela na base de dados Um, porque é parte de uma terceira configuração partido.
Banco de Dados B é o meu próprio banco de dados Oracle 10g, usando a codificação AL32UTF8 para todos os tipos de razões, e eu quero copiar foo para este banco de dados.
Configuração I um link de banco de dados do banco de dados B ao banco de dados A. Então eu emitir o seguinte comando:
* criar bar mesa como select * from # ligação # .foo; *
Os dados são copiados muito bem, mas quando eu verificar os tipos de colunas, noto que CHAR (1 caractere) foi convertido em CHAR (3 caracteres), e ao consultar os dados no banco de dados B, é tudo preenchida com espaços.
Eu acho que em algum lugar debaixo d'água, a Oracle confunde é próprios bytes e caracteres. CHAR (1 byte) é diferente de CHAR (1 caractere) etc. Eu li sobre tudo isso.
Por que a mudança de tipo de dados em um CHAR acolchoado (3 caracteres) e como faço para parar Oracle de fazer isso?
Editar: Parece ter a ver com a transferência CHAR de entre dois diferentes patches específicos da Oracle 9 e 10. Parece que ele é realmente um bug. assim que eu descobrir que eu vou postar uma atualização. Enquanto isso: não tente mover CHAR de entre bancos de dados como eu descrevi. VARCHAR2 funciona bem (testado).
Editar 2: eu encontrei a resposta e postou aqui: Por que Char (1) mudança para Char (3) ao copiar mais de um oracle DBLINK? Pena que eu não posso aceitar a minha própria resposta, porque o meu problema está resolvido.
Solução
Esse problema é causado pela forma como conversões de caracteres Oracle (MIS) pegas entre diferentes conjuntos de caracteres com base na definição comprimento coluna original. Quando você define o tamanho de uma coluna de tipo de caractere em bytes, a Oracle não sabe como fazer uma conversão e bodges TI. A solução é definir sempre o comprimento de um tipo de personagem em caracteres .
Para uma explicação mais aprofundada do problema e como eu descobri isso ter um olhar http://www.rolfje.com / 2008/11/04 / transportação do oracle-chars-over-a-dblink /
Outras dicas
Você precisa aprender a diferença entre o WE8ISO8859P1 NLS (que armazena caracteres em um byte) eo AL32UTF8 que armazena caracteres em até quatro bytes. Você terá que gastar algum tempo de qualidade com o Oracle Support Idioma Nacional (NLS) Documentação . A Oracle faz automaticamente a conversão através do link de banco de dados, em uma tentativa de ser útil.
Tente o seguinte de seu SQL prompt:
ALTER SESSION NLS_NCHAR WE8ISO8859P1
create table bar as select * from #link#.foo;
A primeira coisa que eu tentaria é criar a tabela não como um CTAS mas com uma lista de definições de coluna e tentar executar uma inserção das primeiras alguns milhares de linhas. Se isso não suceder, então seria muito claro por que ... e você teria confirmação rápida de que Thomas Low é morto no preciso.