如何将CLOB数据从一个数据库传输到另一个具有DBLinks的远程ORACLE数据库

如何将CLOB数据从一个数据库传输到另一个具有DBLinks的远程ORACLE数据库,oracle,clob,Oracle,Clob,问题是,如何将CLOB数据从一个源数据库传输到另一个具有DBLINK的Oracle数据库 Oracle无法使用DBLinks传输CLOB数据,因此除了将Oracle中的字段扩展为Varchar2 32.767个字符之外,我们还可以使用什么样的解决方案?Oracle 12的新功能。首先,您需要临时表: create global temporary table TBL_TMP_CLOB ( c_clob CLOB ) 第二次使用“从选择插入”: INSERT INTO schema.remo

问题是,如何将CLOB数据从一个源数据库传输到另一个具有DBLINK的Oracle数据库


Oracle无法使用DBLinks传输CLOB数据,因此除了将Oracle中的字段扩展为Varchar2 32.767个字符之外,我们还可以使用什么样的解决方案?Oracle 12的新功能。

首先,您需要临时表:

create global temporary table TBL_TMP_CLOB
(
  c_clob CLOB
)
第二次使用“从选择插入”:

INSERT INTO schema.remote_table@dblink(rem_clob) SELECT * FROM TBL_TMP_CLOB; 

我发布了一个Github项目,该项目通过数据库链接查询CLOB和BLOB。

以下是独立函数中的CLOB部分:

create or replace function dblink_clob(
    p_dblink    in varchar2
  , p_clob_col  in varchar2
  , p_rid       in urowid
)
return clob is
    /**  A function to fetch a CLOB column over a dblink  **/
    /**  Laurence Prescott 25-Aug-17  **/
    /**  select dblink_clob('some_dblink', 'some_clob_column', rowid)
           from some_table@some_dblink;
         Note: Does not work on tables that have a virtual column (eg. xmltype).
    **/

    c_chunk_size    constant pls_integer := 4000;
    v_chunk         varchar2(4000);
    v_remote_table  varchar2(128);
    v_clob          clob;
    v_pos           pls_integer := 1;
begin
    dbms_lob.createtemporary(v_clob, true, dbms_lob.call);
    execute immediate 'select object_name from user_objects@' ||p_dblink
                   || ' where data_object_id = dbms_rowid.rowid_object(:bv_rid) '
    into v_remote_table using cast (p_rid as rowid);
    loop
        execute immediate 
            'select dbms_lob.substr@' ||p_dblink|| '(' ||p_clob_col|| ', ' ||c_chunk_size
         || ', ' ||v_pos|| ') from ' ||v_remote_table|| '@' ||p_dblink|| ' where rowid = :rid '
        into v_chunk using p_rid;
        begin dbms_lob.append(v_clob, v_chunk);
        exception when others then
            if sqlcode = -6502 then exit; else raise; end if;
        end;
        if length(v_chunk) < c_chunk_size then exit; end if;
        v_pos := v_pos + c_chunk_size;
    end loop;
    return v_clob;
end dblink_clob;
我认为这个例子是不言自明的,但这里有一点描述。 该函数依赖于这样一个事实,即您可以通过dblink调用远程数据库上的函数/过程——在本例中是dbms_lob.substr。 首先,它使用编码到rowid中的对象id查找远程表名。这样就不必将远程表名作为另一个参数传入。 还要注意,p_rid参数是一个urowid,因为它是来自远程数据库的rowid。这就是为什么它需要被铸造。 然后在4000字节的块中提取并重建CLOB,这是PL/SQL中的最大varchar2大小。这些块是varchar2,可以通过dblink传递。 if lengthv_chunk您可以依赖这个catch并完全删除if子句。但我做了一些性能测试,发现在大多数情况下,最好将其保留。

这个全局临时表应该存储什么?@Sylwia Krakowska临时表应该存储CLOB数据,您希望将其传输到远程DBI无法正确解释其工作原因,但是我在我的项目中使用这个方法。所以应该在源端创建临时表,是吗?@Sylwia Krakowska是的,是的。我认为这可以帮助您。我认为这个限制适用于不推荐使用的长列,而不是CLOB列?