2010-08-03 79 views
1

下面是情形:甲骨文CLOB超过DBLINK具有不同字符集

甲骨文答:字符集WE8ISO8859P1

甲骨文B:字符集WE8MSWIN1252

甲骨文甲< - DBLINK - >的Oracle B

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

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

我正在使用“select insert”将文件从B到A,并使用clob_to_blob函数将它们转换为二进制文件here

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

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

有没有解决方法?

在此先感谢

回答

1

您是否尝试过使用[email protected](....)

但你可能想要得到某种远程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 [email protected] 
+0

嗨加里, 不,如果我使用我的客户端的功能(即使与@dblinkname)我仍然得到一个ORA-22992 :( 我认为你唯一的东西可以使用LOBS over dblinks做插入/选择。 远程系统上的文件很好:( 我讨厌当你必须为别人过去的错误决定付费时(二进制文件作为clobs ...) – andrecarlucci 2010-08-05 13:00:47

+0

最后,我设法在远程端创建了一个视图,该视图将clob转换为仍然在远程端的blob,然后我可以随时使用本地数据库中的insert/select。它工作正常! – andrecarlucci 2010-08-12 18:30:41

0

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

  1. 获取一个客户端程序,无论是独立的还是你自己,提取从Oracle CLOB B并将数据写出为包含正确二进制数据的“文本”文件。
  2. 将该文件作为二进制文件导入Oracle A到BLOB中。
+0

嗨Dan,感谢您的回答。 我不能直接访问B,防火墙问题:( – andrecarlucci 2010-08-03 18:46:57

0

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