Oracle使用不同的charset覆盖dblink

时间:2010-08-03 18:28:03

标签: oracle blob character-encoding clob dblink

以下是该方案:

Oracle A:charset WE8ISO8859P1

Oracle B:charset WE8MSWIN1252

Oracle A< - dblink - > Oracle B

我无法直接访问Oracle B,防火墙问题:(

我必须从OracleB获取一些二进制文件,这些文件位于CLOB类型的列中(不要问我为什么,我不能更改为BLOB)。

我正在使用“选择插入”将文件从B转换为A,然后使用找到here的clob_to_blob函数将它们转换为二进制文件。

我收到了一些损坏的文件,我相信这是因为Oracle正在通过dblink自动将WE8MSWIN1252转换为WE8ISO8859P1(好吧,列是CLOB所以它是文本,对吧?)。

我无法以任何方式更改数据库字符集。

有没有解决方法呢?

提前致谢

3 个答案:

答案 0 :(得分:1)

您是否尝试过使用DBMS_LOB.CONVERTTOBLOB@remote(....)

但是你可能希望获得远程CLOB的某种校验和,以查看它们是否在从任何原始外部源插入/更新时获得字符集转换。也就是说,如果客户端字符集在插入完成时与数据库字符集不同,则在进行选择之前可能已经出现问题。


编辑添加。

我能想出的最接近的东西需要链接另一端的一些对象。 首先是在远程端进行转换的函数。 其次是一个呈现数据的“BLOB”视图的视图。 这使用了一个虚拟表(基于v $ sql,因为它是我能找到的第一个CLOB)。没理由我可以看到你不能简单地将CLOB作为参数传递给函数。

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;

然后,从本地数据库中,执行

create table t as select ret_blob from rblob@remote

答案 1 :(得分:0)

我最好的建议是不要使用数据库链接,而是这样做:

  1. 获取独立或自己的客户端程序,从Oracle B中提取CLOB,并将数据写为包含正确二进制数据的“文本”文件。
  2. 将该文件作为二进制文件导入Oracle A进入BLOB。

答案 2 :(得分:0)

完全不同的选择。 使用与B相同的字符集创建数据库C.将数据从B拉到C(不进行任何转换),然后在将数据移动到A之前,可以在C中进行操作。