views:

135

answers:

3

Hello,

Here is the scenario:

Oracle A: charset WE8ISO8859P1

Oracle B: charset WE8MSWIN1252

Oracle A <- dblink -> Oracle B

I can't access Oracle B directly, firewall issues :(

I have to get some binary files from OracleB and these files are in a column of type CLOB (don't ask me why and I can't change to BLOB).

I'm using a "select insert" to get the files from B to A and them converting them to binary using clob_to_blob function found here.

I'm getting some corrupted files and I believe it's because Oracle is converting WE8MSWIN1252 to WE8ISO8859P1 automatically over the dblink (well, the column is CLOB so it's text, right?).

I can't change the databases charsets in any way.

Is there any workaround for this?

Thanks in advance

A: 

My best suggestion would be not to use the DB link but instead do this:

  1. Get a client program, either standalone or your own, to extract the CLOB from Oracle B and write the data out as a "text" file which contains the correct binary data.
  2. Import that file into Oracle A as a binary file into the BLOB.
Dan
Hi Dan, thanks for the answer.I can't access B directly, firewall issues :(
andrecarlucci
+1  A: 

Have you tried to use DBMS_LOB.CONVERTTOBLOB@remote(....)

But you probably want to get some sort of checksum of the remote CLOB to see whether they are getting a characterset conversion when they are inserted/updated from whatever original external source. That is, if the client characterset, when the insert is done, is different from the database characterset, the problem may have already occurred before you do your select.


Edited to add.

The closest I can come up with requires some objects on the other end of the link. Firstly a function that does the conversion at the remote end. Secondly a view that presents a 'BLOB' view of the data. This uses a dummy table (based of v$sql as it was the first CLOB I could find). No reason I can see that you can't simply pass the CLOB as a parameter to the function.

create or replace function ret_blob return blob is
  cursor c_1 is 
  select sql_fulltext, sql_id, length(sql_fulltext) 
  from v_sql
  where sql_id = 'bzmb01whp36wt';
  rec_c1 c_1%rowtype;
  --
  v_blob  blob;
  v_dest  number := 1;
  v_src   number := 1;
  v_lang  number := 0;
  v_warn  number;
  --
begin
  open c_1;
  fetch c_1 into rec_c1;
  close c_1;
  dbms_lob.createtemporary(v_blob, TRUE);
  --
  dbms_lob.CONVERTTOBLOB (v_blob, rec_c1.sql_fulltext, DBMS_LOB.LOBMAXSIZE, 
        v_dest, v_src, DBMS_LOB.DEFAULT_CSID, v_lang, v_warn);
  --
  dbms_output.put_line(':'||v_warn||'>'||length(v_blob));
  --
  return v_blob;
end;
/

create view rblob as select ret_blob from dual;

Then, from the local database, do a

create table t as select ret_blob from rblob@remote
Gary
Hi Gary,No, if I use the function from my client (even with @dblinkname) I still get an ORA-22992 :(I think the only thing you can do with LOBS over dblinks is an insert/select.The files are fine on the remote system :(I hate when you have to pay for someone else's bad decision in the past (binary files as clobs...).
andrecarlucci
Finally I managed to get a view created on the remote side. This view converts the clob to blob still in remote side and then I can use insert/select from the local database anytime I want. It worked! Tks for the view idea.
andrecarlucci
A: 

A totally different alternative. Create database C with the same characterset as B. Pull the data from B to C (without any conversion), then you can do you manipulation in C before moving the data to A.

Gary