Pular para o conteúdo
Visualizando 7 posts - 1 até 7 (de 7 do total)
  • Autor
    Posts
  • #106167
    Avatar de antognolliantognolli
    Participante

      Senhores, boa tarde.

      Estou com dificuldade em converter um campo LONG RAW para CLOB. Ex:


      CREATE TABLE TAB_RAW(
      CONTEUDO_RAW LONG RAW
      );
      /
      CREATE TABLE TAB_CLOB(
      CONTEUDO_CLOB CLOB
      );

      INSERT INTO TAB_RAW (CONTEUDO_RAW) VALUES ('5445535445'); --PALAVRA TESTE NO FORMATO HEXADECIMAL
      INSERT INTO TAB_CLOB (CONTEUDO_CLOB) VALUES ('TESTE'); --PALAVRA TESTE FORMATO CLOB
      COMMIT;

      --Exemplos de ERRO DE CONVERSÃO
      SELECT * FROM TAB_RAW WHERE CONTEUDO_RAW = (SELECT CONTEUDO_CLOB FROM TAB_CLOB);
      SELECT * FROM TAB_RAW WHERE CONTEUDO_RAW = '';

      No exemplo acima eu inseri a plavra “TESTE” na tabela TAB_RAW no formato HEXADECIMAL e também inseri na tabela TAB_CLOB.

      Porém quando eu tento fazer o select na tabela TAB_RAW ocorre erro ORA-00997, alguém pode ajudar?

      Pesquisei no ASK TOM, STACK OVERFLOW, Fórum ORACLE, Neste Fórum e não resolveu.

      Abraço

      #106168
      Avatar de rmanrman
      Participante

        @antognolli

        Segue artigo com a solução:

        http://www.aired.in/2012/07/how-to-convert-from-long-raw-to.html

        #106169
        Avatar de antognolliantognolli
        Participante

          Rman, obrigado pela resposta.

          Compilei a procedure no meu banco e usando o PL/SQL Developer abri uma janela para testar a procedure.

          begin
          -- Call the procedure
          long2lob(p_longquery => :p_longquery,
          p_clob => :p_clob);
          end;

          No parâmetro “p_longquery” eu coloquei o valor:
          SELECT CONTEUDO_RAW FROM TAB_RAW

          Quando executei a procedure houve o seguinte erro:
          ORA-00932: inconsistent datatypes: expected NUMBER got LONG BINARY
          ORA-06512: at “LONG2LOB”, line 32
          ORA-06512: at line 3

          View program sources of error stack?

          VOcê chegou a utilizar essa solução? Estou usando errado a procedure?

          (As soluções para criar uma tabela para conversão não interessam devido aos requisitos da atividade)

          Abraço
          Bruno

          #106170
          Avatar de rmanrman
          Participante

            @antognolli

            Acabei de testar aqui e realmente aqui também deu o mesmo erro. :blink:

            #106171
            Avatar de antognolliantognolli
            Participante

              Rman,

              Realmente estranho… vou tentar por outro caminho…

              Volto aqui para dizer como foram os outros testes!

              Obrigado pela ajuda! 😉

              Abs,
              Bruno

              #106172
              Avatar de antognolliantognolli
              Participante

                Rman

                Outro link interessante onde o Chiapa diz “uma das restrições dos LONG RAWs é que eles NÂO podem participar diretamente de comando na linguagem SQL”

                https://www.mail-archive.com/oracle_br@yahoogrupos.com.br/msg02420.html

                Sendo assim, criei duas funções
                BLOB -> CLOB
                CLOB -> BLOB
                Uma tabela temporária e um bloco anônimo para comparar os BLOBS.

                Vamos por partes:
                Criar função CLOB -> BLOB
                create or replace function CLOB_TO_BLOB (p_clob CLOB) return BLOB
                as
                l_blob blob;
                l_dest_offset integer := 1;
                l_source_offset integer := 1;
                l_lang_context integer := DBMS_LOB.DEFAULT_LANG_CTX;
                l_warning integer := DBMS_LOB.WARN_INCONVERTIBLE_CHAR;
                BEGIN

                DBMS_LOB.CREATETEMPORARY(l_blob, TRUE);
                DBMS_LOB.CONVERTTOBLOB
                (
                dest_lob =>l_blob,
                src_clob =>p_clob,
                amount =>DBMS_LOB.LOBMAXSIZE,
                dest_offset =>l_dest_offset,
                src_offset =>l_source_offset,
                blob_csid =>DBMS_LOB.DEFAULT_CSID,
                lang_context=>l_lang_context,
                warning =>l_warning
                );
                return l_blob;
                END;

                Criar função BLOB -> CLOB
                CREATE OR REPLACE FUNCTION blob_to_clob (blob_in IN BLOB)
                RETURN CLOB
                AS
                v_clob CLOB;
                v_varchar VARCHAR2(32767);
                v_start PLS_INTEGER := 1;
                v_buffer PLS_INTEGER := 32767;
                BEGIN
                DBMS_LOB.CREATETEMPORARY(v_clob, TRUE);

                FOR i IN 1..CEIL(DBMS_LOB.GETLENGTH(blob_in) / v_buffer)
                LOOP

                v_varchar := UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(blob_in, v_buffer, v_start));

                DBMS_LOB.WRITEAPPEND(v_clob, LENGTH(v_varchar), v_varchar);

                v_start := v_start + v_buffer;
                END LOOP;

                RETURN v_clob;

                END blob_to_clob;

                Tabela temporária
                CREATE GLOBAL TEMPORARY TABLE TMP_CONVERTEBIO
                (
                TEMP_BIO BLOB
                )ON COMMIT DELETE ROWS;

                DELETAR O CONTEÚDO DA TABELA PARA EVITAR PROBLEMAS
                DELETE FROM TAB_CLOB;
                COMMIT;

                Bloco Anonimo
                DECLARE
                V_lORIGEM BLOB; --campo BLOB de origem
                V_lDESTINO CLOB; --campo CLOB para destino
                V_COMP BLOB; --campo BLOB para comparação

                V_nSEQ              PLS_INTEGER;   
                Retval              INTEGER;    
                Amount              INTEGER := 32767;    
                

                BEGIN
                --INSERE LONG RAW EM TABELA TEMPORARIA TIPO CLOB
                INSERT INTO TMP_CONVERTEBIO
                SELECT TO_LOB(CONTEUDO_RAW)
                FROM TAB_RAW;

                --TABELA TEMPORARIA       
                SELECT TEMP_BIO
                  INTO V_lORIGEM
                  FROM TMP_CONVERTEBIO;    
                

                --CONVERTE BLOB para CLOB e grava na tabela
                INSERT INTO TAB_CLOB VALUES (BLOB_TO_CLOB(V_lORIGEM));

                --Recupera o dado da tabela, converte para BLOB e compara com "LONG RAW"
                SELECT CLOB_TO_BLOB(CONTEUDO_CLOB) INTO V_COMP FROM TAB_CLOB;

                /* Compara BLOBS*/
                retval := DBMS_LOB.COMPARE(V_lORIGEM, V_COMP, Amount, 1, 1);
                IF retval = 0 THEN
                   DBMS_OUTPUT.PUT_LINE('DADOS IGUAIS');
                ELSE
                   DBMS_OUTPUT.PUT_LINE('DADOS DIFERENTES');
                END IF;
                

                END;
                /

                Após executar o bloco anonimo o DBMS irá “printar” que os dados são iguais.
                SELECT * FROM TAB_RAW
                SELECT * FROM TAB_CLOB

                Nesse exemplo, eu pego os dados LONG RAW converto para BLOB, em seguida converto o BLOB para CLOB e gravo na tabela TAB_CLOB.

                Depois recupero os dados da TAB_CLOB convertendo para BLOB e verifico com os dados de origem (que é o LONG RAW convertido para BLOB através da tabela temporária)

                Uffa, testei e funcionou!

                Abraços,
                Bruno.

                #106173
                Avatar de rmanrman
                Participante

                  @antognolli

                  Li uma vez que LONG e LONG RAW são obsoletos, que era pra utilizar CLOB e BLOB.

                  Mas que trabalheira pra converter esse bendito :blink:

                Visualizando 7 posts - 1 até 7 (de 7 do total)
                • Você deve fazer login para responder a este tópico.
                plugins premium WordPress