代码之家  ›  专栏  ›  技术社区  ›  andrecarlucci

具有不同字符集的DBLink上的Oracle CLOB

  •  1
  • andrecarlucci  · 技术社区  · 14 年前

    以下是场景:

    甲骨文A:Charset WE8ISO8859P1

    Oracle B:Charset WE8MSwin1252

    Oracle A<-dblink->Oracle B

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

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

    我使用“select insert”将文件从B转换为A,然后使用clob_to_blob函数将文件转换为二进制文件。 here .

    我收到了一些损坏的文件,我认为这是因为Oracle正在通过dblink自动将we8mswin1252转换为we8iso8859p1(好吧,列是clob,所以它是文本,对吗?).

    我不能以任何方式更改数据库字符集。

    有什么解决办法吗?

    提前谢谢

    3 回复  |  直到 14 年前
        1
  •  1
  •   Gary Myers    14 年前

    是否尝试使用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
    
        2
  •  0
  •   Dan    14 年前

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

    1. 获取一个独立的或您自己的客户机程序,从OracleB中提取CLOB,并将数据作为包含正确二进制数据的“文本”文件写出。
    2. 将该文件作为二进制文件导入到blob中。
        3
  •  0
  •   Gary Myers    14 年前

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