Skip to Main Content

Breadcrumb

Question and Answer

Chris Saxon

Thanks for the question, Bhogesh.

Asked: April 29, 2019 - 2:49 pm UTC

Last updated: April 30, 2019 - 1:53 pm UTC

Version: 12.1

Viewed 1000+ times

You Asked

Hi Tom how to write the table data into clob column in another table in oracle 12.1 version

create table abc(sno number(2) not null,file_clob clob);

insert into abc(sno) values(1);
insert into abc(sno) values(2);
insert into abc(sno) values(3);

create table rem(sno number(2), name varchar2(10),address varchar2(10));
insert into rem (sno,name,address) values (1,'anc','err');
insert into rem (sno,name,address)values(2,'sjd','djjd');
insert into rem (sno,name,address) values(2,'sjd','sdjd');
insert into rem (sno,name,address)values (2,'kfkf','kkkd');


create or replace TYPE type_sno FORCE AS OBJECT
( 
 sno number(2 )
);
/

create or replace TYPE type_sno_values  FORCE AS TABLE OF type_sno;
/

create or replace procedure insert_to_clob(pi_sno IN type_sno_values)
as

 cright  clob;
 cright1   clob;
 header   varchar2(1000):='ancsjsjjsjsjjssjsjjssjsjsjjs';
cursor input_sno is select osd.sno from table(pi_sno) osd;
 begin
 for task in input_sno loop 
 UPDATE abc
            SET file_clob  = empty_clob()
            WHERE sno = task.sno
            RETURNING file_clob  
         INTO cright;
        dbms_lob.writeappend(cright,length(header),header);
   cright1:=cright;
  cright1:=empty_clob();
FOR i IN ( SELECT CHR(10)
                || sno  || ';'
                || name  || ';'
                || address str
            FROM
                rem
            WHERE
                sno = task.sno) loop
 cright1:=cright1||i.str;
-- dbms_output.put_line(v_cwrite1);
 if(length(cright1)>=32000 or i.str.last )  then 
dbms_lob.writeappend(cright,length(cright1),cright1);
   end if;
 end loop;

 end loop;
 EXCEPTION
    WHEN OTHERS THEN
        RAISE;
end;


my above program is not giving the expected output, the expected out in abc clob as follows.

For abc table colb (FILE_CLOB)column for sno 1.

ancsjsjjsjsjjssjsjjssjsjsjjs
anc;err

For abc table colb (FILE_CLOB)column for sno 2.

ancsjsjjsjsjjssjsjjssjsjsjjs
sjd;djjd
sjd;djjd
sjd;sdjd

when cright1 is >=32000 or i.str last then the data should be updated into abc table (FILE_CLOB) column.

1)i am unable to code for the above if condition.
2)I am not getting the expected output form above program.
3)Is there any good approach on performance wise.

and Chris said...

I'm a bit confused as to what you're trying to do here. But if you want to append values to a CLOB column, you only need to append to the variable your update returns.

No need for length checking or an intermediate value.

For example:

create or replace procedure insert_to_clob (
  pi_sno in type_sno_values
) as

  cright    clob;
  header    varchar2 (1000) := 'ancsjsjjsjsjjssjsjjssjsjsjjs';
  cursor input_sno is
  select osd.sno
  from   table (pi_sno) osd;

begin 
  for task in input_sno loop
    update abc
    set   file_clob = empty_clob ()
    where sno = task.sno 
    returning file_clob into cright;
  
    dbms_lob.writeappend (cright,length (header),header);

    for i in ( 
      select chr (10) || name || ';' || address as str 
      from rem
      where sno = task.sno
    ) loop
    
      dbms_lob.writeappend (cright,length (i.str),i.str);

    end loop;
  end loop;
end;
/

select * from abc;

SNO   FILE_CLOB   
     1 <null>       
     2 <null>       
     3 <null>  

begin
  insert_to_clob (
    type_sno_values ( type_sno ( 1 ) )
  );
  
  insert_to_clob (
    type_sno_values ( type_sno ( 2 ) )
  );
end;
/

select * from abc;

SNO   FILE_CLOB                                                  
     1 ancsjsjjsjsjjssjsjjssjsjsjjs
anc;err                        
     2 ancsjsjjsjsjjssjsjjssjsjsjjs
sjd;djjd
sjd;sdjd
kfkf;kkkd    
     3 <null>  


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

More to Explore

SQL

The Oracle documentation contains a complete SQL reference.