- Este tópico contém 6 respostas, 2 vozes e foi atualizado pela última vez 10 anos, 11 meses atrás por rman.
-
AutorPosts
-
6 de dezembro de 2013 às 8:08 pm #106167antognolliParticipante
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
6 de dezembro de 2013 às 8:57 pm #106168rmanParticipante@antognolli
Segue artigo com a solução:
http://www.aired.in/2012/07/how-to-convert-from-long-raw-to.html
6 de dezembro de 2013 às 9:30 pm #106169antognolliParticipanteRman, 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_RAWQuando 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 3View 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
Bruno6 de dezembro de 2013 às 10:21 pm #106170rmanParticipante@antognolli
Acabei de testar aqui e realmente aqui também deu o mesmo erro. :blink:
6 de dezembro de 2013 às 10:43 pm #106171antognolliParticipanteRman,
Realmente estranho… vou tentar por outro caminho…
Volto aqui para dizer como foram os outros testes!
Obrigado pela ajuda! 😉
Abs,
Bruno6 de dezembro de 2013 às 11:56 pm #106172antognolliParticipanteRman
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;
BEGINDBMS_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)
LOOPv_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çãoV_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_CLOBNesse 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.9 de dezembro de 2013 às 2:34 pm #106173rmanParticipante@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:
-
AutorPosts
- Você deve fazer login para responder a este tópico.