Ошибка CLOB2FILE в случае превышения размера 64k 
	   
	     | 
   
 
	
		| Предыдущая тема :: Следующая тема   | 
	 
	
	
		| Автор | 
		Сообщение | 
	 
	
		Матвеев Евгений Профи
 
  Вступление в Клуб: 31.01.2012
  | 
		
			
				 Вт Авг 23, 2016 13:18   Ошибка CLOB2FILE в случае превышения размера 64k | 
				     | 
			 
			
				Полезность: Нет оценки 
  | 
			 
			
				Делаю экспорт в xml
 
выгружаю так
 
 
 	  | Код: | 	 		  
 
procedure SaveXmlFile(p_file_name varchar2(255), p_dir_name varchar2(255), p_xml &xml.DOMDocument)
 
is
 
   file_path varchar2(255) := replace([SYSTEM_PARAMS]::[GET]('PATH',null)||p_dir_name,'/',slash);
 
   f_clob CLOB;
 
begin
 
   dbms_lob.createtemporary(f_clob, false);
 
   &xml.writeToClob(p_xml, f_clob);-- выгрузка в CLOB
 
   clob2file(f_clob, file_path, p_file_name,'UTF8');
 
   dbms_lob.freetemporary(f_clob);   
 
end;
 
 | 	  
 
 
Если p_xml (а соответственно и f_clob) менее 64k, всё гуд, файлы формируются
 
 
Если более 64k, то
 
 
 
 
 	  | Цитата: | 	 		  
 
В настоящий момент операция невозможна:
 
PL/SQL: : буфер символьных строк слишком маленький ошибка числа или значения
 
 
ORA-06502: PL/SQL: : буфер символьных строк слишком маленький ошибка числа или значения
 
 
ORA-06512: на  "IBS.Z$FM_MESS_SET_RCI_SAVE_MESS", line 38
 
 
ORA-06512: на  "IBS.Z$FM_MESS_SET_RCI_SAVE_MESS", line 57
 
 
ORA-06512: на  "IBS.Z$FM_MESS_SET_RCI_SAVE_MESS", line 201
 
 
ORA-06512: на  "IBS.Z$U$3158650867", line 75
 
 
ORA-06512: на  line 1
 
 
BEGIN
 
 
	$$$.Z$U$3158650867.P(?,?,?);
 
 
END;
 
 | 	  
 
 
Как быть? | 
			 
		  | 
	 
	
		  | 
	 
	
		OlegFB Участник - экстремал
 
  Вступление в Клуб: 11.07.2007
  | 
		
			
				 Вт Авг 23, 2016 15:27   Re: Ошибка CLOB2FILE в случае превышения размера 64k | 
				     | 
			 
			
				Полезность: 2 
  | 
			 
			
				 	  | Матвеев Евгений пишет: | 	 		  Делаю экспорт в xml
 
выгружаю так
 
 
 	  | Код: | 	 		  
 
procedure SaveXmlFile(p_file_name varchar2(255), p_dir_name varchar2(255), p_xml &xml.DOMDocument)
 
is
 
   file_path varchar2(255) := replace([SYSTEM_PARAMS]::[GET]('PATH',null)||p_dir_name,'/',slash);
 
   f_clob CLOB;
 
begin
 
   dbms_lob.createtemporary(f_clob, false);
 
   &xml.writeToClob(p_xml, f_clob);-- выгрузка в CLOB
 
   clob2file(f_clob, file_path, p_file_name,'UTF8');
 
   dbms_lob.freetemporary(f_clob);   
 
end;
 
 | 	  
 
 
Если p_xml (а соответственно и f_clob) менее 64k, всё гуд, файлы формируются
 
 
Если более 64k, то
 
 
 
 
 	  | Цитата: | 	 		  
 
В настоящий момент операция невозможна:
 
PL/SQL: : буфер символьных строк слишком маленький ошибка числа или значения
 
 
ORA-06502: PL/SQL: : буфер символьных строк слишком маленький ошибка числа или значения
 
 
ORA-06512: на  "IBS.Z$FM_MESS_SET_RCI_SAVE_MESS", line 38
 
 
ORA-06512: на  "IBS.Z$FM_MESS_SET_RCI_SAVE_MESS", line 57
 
 
ORA-06512: на  "IBS.Z$FM_MESS_SET_RCI_SAVE_MESS", line 201
 
 
ORA-06512: на  "IBS.Z$U$3158650867", line 75
 
 
ORA-06512: на  line 1
 
 
BEGIN
 
 
	$$$.Z$U$3158650867.P(?,?,?);
 
 
END;
 
 | 	  
 
 
Как быть? | 	  
 
Насколько я в курсе - никак не лечится.
 
Мы обходили костыликом: в  цикле вычитывали данные блоками по сколько-то там Кб и писали в файл уже эти блоки частями. | 
			 
		  | 
	 
	
		  | 
	 
	
		Матвеев Евгений Профи
 
  Вступление в Клуб: 31.01.2012
  | 
		
			
				 Вт Авг 23, 2016 15:30    | 
				     | 
			 
			
				Полезность: Нет оценки 
  | 
			 
			
				А есть пример костылика?
 
 
Костылика на запись...
 
 
и
 
 
Костылика на чтение... | 
			 
		  | 
	 
	
		  | 
	 
	
		OlegFB Участник - экстремал
 
  Вступление в Клуб: 11.07.2007
  | 
		 | 
	 
	
		  | 
	 
	
		Матвеев Евгений Профи
 
  Вступление в Клуб: 31.01.2012
  | 
		
			
				 Вт Авг 23, 2016 22:26    | 
				     | 
			 
			
				Полезность: Нет оценки 
  | 
			 
			
				Наверное как то так это должно выглядеть 
 
 
 	  | Код: | 	 		  
 
procedure clob2file(p_file_path varchar2(2000),p_file_name varchar2(2048),cl clob) is
 
   file      integer;
 
   buffer      varchar2(32000);
 
   idx       integer:=1;
 
begin
 
   file := stdio.open(p_file_path, p_file_name,'w');
 
 
   buffer:=substr(cl,idx,32000);
 
    while length(buffer) != 0
 
    loop
 
       stdio.fput(file,buffer,true);
 
       idx:=idx+32000;
 
       buffer:=substr(cl,idx,32000);
 
    end loop;
 
    stdio.close(file);
 
end;
 
 | 	  
 
 
 
Костылик на запись кусочками по 32000 байт | 
			 
		  | 
	 
	
		  | 
	 
	
		Alkov Профи
 
  Вступление в Клуб: 23.09.2010
  | 
		
			
				 Ср Авг 24, 2016 02:29    | 
				     | 
			 
			
				Полезность: 1 
  | 
			 
			
				у меня кодировка так не та сохранялась, конвертил в blob типа такого:
 
 	  | Код: | 	 		  
 
procedure write_to_file
 
         ( p_clob   in      clob
 
         , p_dir            varchar
 
         , p_fname         varchar
 
         )
 
is
 
 
v_blob   blob;
 
iFile      integer;
 
rwChunk   raw(32767);
 
iSize      integer  := 32765;   --   запланированный объем порции данных
 
 
lang_ctx   dbms_lob.default_lang_ctx%type := dbms_lob.default_lang_ctx;
 
dest_offs   integer :=1;
 
src_offs   integer :=1;
 
warn      integer;
 
utf8_sid   integer := 873;    -- AL32UTF8
 
win_sid   integer := 171;    -- CL8MSWIN1251
 
lenb      number;
 
cnt      integer;
 
begin
 
   dbms_lob.createtemporary(v_blob, true, dbms_lob.call);
 
   
 
   dbms_lob.convertToBlob(v_blob, p_clob, dbms_lob.lobmaxsize, dest_offs, src_offs, utf8_sid, lang_ctx, warn);
 
   
 
   iFile := stdio.open(p_dir, p_fname, 'w');       
 
 
   lenb := dbms_lob.getlength(v_blob);
 
   if lenb <> 0 then      
 
      cnt := ceil(lenb / iSize);
 
      for i in 1 .. cnt loop
 
         dbms_lob.read(v_blob , iSize, (i - 1) * iSize + 1, rwChunk);
 
         stdio.fwrite(iFile, rwChunk,  utl_raw.length(rwChunk) );
 
      end loop;
 
   end if;
 
   
 
   stdio.f_close(iFile);
 
end;
 
 | 	 
  | 
			 
		  | 
	 
	
		  | 
	 
	
		Матвеев Евгений Профи
 
  Вступление в Клуб: 31.01.2012
  | 
		
			
				 Ср Авг 24, 2016 02:33    | 
				     | 
			 
			
				Полезность: 1 
  | 
			 
			
				Тоже сейчас столкнулся, минут 40 убил, в итоге решил вот так:
 
 
 	  | Код: | 	 		  
 
 
 
procedure clob2file(p_clob CLOB , p_filedir varchar2, p_filename varchar2, codePage varchar2 default null) is
 
file integer;
 
buf_size const integer := 32000;
 
amount integer := buf_size;
 
offset integer := 1;
 
buffer VARCHAR2(32000);
 
buffer_conv varchar2(32000);
 
buffer_row    raw(32000);
 
our_charset varchar2;
 
begin
 
   if codePage is not null then   
 
      select a(a.value) in NLS_DATABASE_PARAMETERS%rowtype where a.PARAMETER = 'NLS_CHARACTERSET' into our_charset;
 
   end if;
 
   file := stdio.f_open(p_filedir||slash||p_filename, 'w');
 
   &debug('p_filename=['||p_filedir||slash||p_filename||']',1);
 
   while amount = buf_size loop
 
      dbms_lob.read(p_clob, amount, offset, buffer);
 
      buffer_conv := convert(buffer, codePage, our_charset);
 
      buffer_row := utl_raw.cast_to_raw(buffer_conv);
 
      stdio.f_write(file, buffer_row);
 
      --stdio.write_str(file, , null, null, false);
 
      offset := offset + amount;
 
   end loop;
 
   stdio.f_close(file);
 
end;
 
 
...
 
clob2file(f_clob, file_path, p_file_name,'CL8MSWIN1251');
 
...
 
 | 	  
 
 
Подходит кодировка CL8MSWIN1251
 
 
 	  | Код: | 	 		  
 
<?xml version="1.0" encoding="ISO-8859-5"?>
 
<Main>
 
  <FmMessSet BANK_PRODUCT="CUSTOMER_SERVICE_9" WAY_SELL="CS9_CHDP">
 
    <FmMessages STATUS="CS_REPLY" TYPE_INFO="SMS" COND="FM_MESSAGE" TEMPLATE="ЧДП Регистрация заявки SMS">
 
      <RECIP_CLIENTS PARTICIPANT_CODE="REQUESTER" PARTICIPANT_NAME="Инициатор запроса"/>
 
    </FmMessages>
 
    <FmMessages STATUS="CS_REPLY" TYPE_INFO="MAIL" COND="FM_MESSAGE" TEMPLATE="ЧДП Регистрация заявки">
 
      <RECIP_OTHER NAME="sergey.panin-extern@bank.ru" CONTACT="sergey.panin-extern@bank.ru"/>
 
    </FmMessages>
 
    <FmMessages STATUS="CS_REPLY" TYPE_INFO="MAIL" COND="CS_MAIL_ERROR_DATA" TEMPLATE="ЧДП\ПДП Отказ">
 
      <RECIP_OTHER NAME="sergey.panin-extern@bank.ru" CONTACT="sergey.panin-extern@bank.ru"/>
 
    </FmMessages>
 
    <FmMessages STATUS="CS_REPLY" TYPE_INFO="SMS" COND="CS_MAIL_ERROR_DATA" TEMPLATE="ЧДП\ПДП Отказ SMS">
 
      <RECIP_CLIENTS PARTICIPANT_CODE="REQUESTER" PARTICIPANT_NAME="Инициатор запроса"/>
 
    </FmMessages>
 
    <FmMessages STATUS="CS_REPLY" TYPE_INFO="SMS" COND="FM_MESSAGE" TEMPLATE="ПДП Регистрация заявки SMS">
 
      <RECIP_CLIENTS PARTICIPANT_CODE="REQUESTER" PARTICIPANT_NAME="Инициатор запроса"/>
 
    </FmMessages>
 
    <FmMessages STATUS="CS_REPLY" TYPE_INFO="SMS" COND="FM_MESSAGE" TEMPLATE="ЧДП\ПДП Отказ SMS - кредитный договор закрыт">
 
      <RECIP_CLIENTS PARTICIPANT_CODE="REQUESTER" PARTICIPANT_NAME="Инициатор запроса"/>
 
    </FmMessages>
 
    <FmMessages STATUS="CS_REPLY" TYPE_INFO="MAIL" COND="FM_MESSAGE" TEMPLATE="ПДП Регистрация заявки">
 
      <RECIP_OTHER NAME="sergey.panin-extern@bank.ru" CONTACT="sergey.panin-extern@bank.ru"/>
 
    </FmMessages>
 
    <FmMessages STATUS="CS_REPLY" TYPE_INFO="MAIL" COND="FM_MESSAGE" TEMPLATE="ЧДП\ПДП Отказ - кредитный договор закрыт">
 
      <RECIP_OTHER NAME="sergey.panin-extern@bank.ru" CONTACT="sergey.panin-extern@bank.ru"/>
 
    </FmMessages>
 
  </FmMessSet>
 
</Main>
 
 
 | 	 
  | 
			 
		  | 
	 
	
		  | 
	 
	
		 | 
	 
 
  
	 
	    
	   | 
	
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете голосовать в опросах
  | 
   
 
		 |