AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 175411
Accepted
Malvineous
Malvineous
Asked: 2017-06-06 01:12:21 +0800 CST2017-06-06 01:12:21 +0800 CST 2017-06-06 01:12:21 +0800 CST

CONVERT() retorna lixo com CLOBs no Oracle

  • 772

Estou procurando reparar uma tabela de dados no Oracle, de preferência via SQL sem privilégios, que teve dados UTF-8 inseridos em um banco de dados UTF-8, usando o conjunto de caracteres Latin-1 por engano.

O símbolo β GREEK SMALL LETTER BETAdeveria ter entrado no banco de dados, mas em vez disso os dois caracteres βforam... como os dois caracteres UTF-8 Î LATIN CAPITAL LETTER I WITH CIRCUMFLEXseguidos por ² SUPERSCRIPT TWO.

Este código de exemplo demonstra o problema e a correção, mas só funciona com VARCHARcolunas. Assim que a CLOBé usado, a conversão falha:

-- This must return AL32UTF8 for this example to be valid
SELECT VALUE FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER='NLS_CHARACTERSET';

CREATE TABLE EXAMPLE (T VARCHAR2(20));
INSERT INTO EXAMPLE (T) VALUES ('Example β');
SELECT T FROM EXAMPLE; -- Should return 'Example β'
SELECT CONVERT(T, 'WE8ISO8859P1') FROM EXAMPLE;
UPDATE EXAMPLE SET T=CONVERT(T, 'WE8ISO8859P1');
SELECT T FROM EXAMPLE; -- Should return 'Example β', problem fixed
DROP TABLE EXAMPLE;

No entanto, se o VARCHAR2(20)for alterado para CLOB, isso não funcionará mais. CONVERT()retorna caracteres de lixo. Eu posso usar TO_CHAR()para contornar o problema, mas eventualmente recebo um erro que CLOBtem mais de 4000 caracteres, então TO_CHAR()falha.

Existe uma maneira de fazer o exemplo acima funcionar, ao usar uma CLOBcoluna com mais de 4000 caracteres?

oracle character-set
  • 1 1 respostas
  • 9745 Views

1 respostas

  • Voted
  1. Best Answer
    Balazs Papp
    2017-06-06T05:02:45+08:002017-06-06T05:02:45+08:00

    DBMS_LOBpacote também tem funções de conversão. Infelizmente, não há suporte para converter CLOB em CLOB e alterar o conjunto de caracteres em uma etapa, então os dados são convertidos primeiro em BLOB e depois de volta em CLOB.

    CREATE TABLE EXAMPLE (T CLOB);
    INSERT INTO EXAMPLE (T) VALUES ('Example β ');
    
    begin
      for i in 1..12
      loop
        update example set t = t || t;
      end loop;
      commit;
    end;
    /
    
    select dbms_lob.getlength(t) from example;
    
    DBMS_LOB.GETLENGTH(T)
    ---------------------
                    45056
    

    Agora a parte da conversão:

    create or replace function repair_data (p_clob clob) return clob as
      l_blob blob; 
      l_dest_offset number := 1;
      l_src_offset number := 1;
      l_lang_context number := 0;
      l_warning number;
      l_result clob;
    begin
      dbms_lob.createtemporary(l_blob, true, dbms_lob.call);
      dbms_lob.createtemporary(l_result, true, dbms_lob.call);
      dbms_lob.converttoblob(l_blob, p_clob, dbms_lob.lobmaxsize, l_dest_offset, l_src_offset,
                             nls_charset_id('WE8ISO8859P1'), l_lang_context, l_warning);
      l_dest_offset := 1;
      l_src_offset := 1;
      l_lang_context := 0;
      dbms_lob.converttoclob(l_result, l_blob, dbms_lob.lobmaxsize, l_dest_offset, l_src_offset,
                             nls_charset_id('AL32UTF8'), l_lang_context, l_warning);
      return l_result;
    end;
    /
    
    select repair_data(T) from example;
    
    REPAIR_DATA(T)                          
    ----------------------------- 
    Example β Example β Example β ...
    
    update example set t = repair_data(t);
    ...
    
    • 5

relate perguntas

  • Backups de banco de dados no Oracle - Exportar o banco de dados ou usar outras ferramentas?

  • ORDER BY usando prioridades personalizadas para colunas de texto

  • Interface sqlplus confortável? [fechado]

  • Como encontrar as instruções SQL mais recentes no banco de dados?

  • Como posso consultar nomes usando expressões regulares?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve