Skip to Main Content
  • Questions
  • Clobs over dblink - chunking function (buffer to small)

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, Paul .

Asked: April 21, 2023 - 12:16 pm UTC

Last updated: May 10, 2023 - 3:39 am UTC

Version: 19c

Viewed 1000+ times

You Asked

We have a chunking function we borrowed to bring back CLOBS over a DB Link in Oracle:

create or replace function fn_dblink_clob(
    p_dblink    in varchar2
  , v_remote_table in varchar2
  , p_clob_col  in varchar2
  , p_rid       in urowid
)
return clob is
    /**  A function to fetch a CLOB column over a dblink  **/
    /** 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(5000);
    v_clob          clob;
    v_pos           pls_integer := 1;
begin
    dbms_lob.createtemporary(v_clob, true, dbms_lob.call);
    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 fn_dblink_clob;


It has worked well, but we are no seeing it throw this error:

ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 1
ORA-02063: preceding 2 lines from SAPP_TRANSCT_DB
ORA-06512: at "PV_COMPLIANCE.FN_DBLINK_CLOB", line 22
06502. 00000 - "PL/SQL: numeric or value error%s"
*Cause: An arithmetic, numeric, string, conversion, or constraint error
occurred. For example, this error occurs if an attempt is made to
assign the value NULL to a variable declared NOT NULL, or if an
attempt is made to assign an integer larger than 99 to a variable
declared NUMBER(2).
*Action: Change the data, how it is manipulated, or how it is declared so
that values do not violate constraints.
CLOBS over DBLINKs are my arch nemesis. I don't know which record is causing it, and dont want to iterate over 5 million records in a cursor to see where it breaks.

Any ideas appreciated.

oracleclob

and Connor said...

Things have gotten better over time - for example, from my 2 19c instancex

db1
----
SQL> create table t ( c clob );

Table created.

SQL> insert into t
  2  values (rpad('x',120000,'x'));

1 row created.

SQL> commit;

Commit complete.

db2
----
SQL> create database link xxx connect to scott identified by tiger using '192.168.1.182:1521/pdb1';

Database link created.

SQL> create table t ( c1 clob);

Table created.

SQL> insert into t
  2  select * from t@xxx;

1 row created.


And reason you can't just do that?

(Worst case, the local table can be a GTT to copy the clob - that approach should work all the way back to 11g I think)


Is this answer out of date? If it is, please let us know via a Comment

More to Explore

Administration

Need more information on Administration? Check out the Administrators guide for the Oracle Database