1

这是场景:

Oracle A:字符集 WE8ISO8859P1

Oracle B:字符集 WE8MSWIN1252

甲骨文 A <- dblink -> 甲骨文 B

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

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

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

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

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

有什么解决方法吗?

提前致谢

4

3 回答 3

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
于 2010-08-03T23:05:29.587 回答
0

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

  1. 获取一个独立的或您自己的客户端程序,以从 Oracle B 中提取 CLOB,并将数据作为包含正确二进制数据的“文本”文件写入。
  2. 将该文件作为二进制文件导入到 BLOB 中的 Oracle A。
于 2010-08-03T18:44:06.587 回答
0

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

于 2010-08-05T23:01:56.190 回答