Как использовать Oracle utl_file для записи изображения clob

У меня есть приложение Oracle Apex, которое генерирует автоматические электронные письма. В Apex пользователь вставляет изображение JPG в поле форматированного текста. Это изображение сохраняется в поле CLOB. При вызове хранимой процедуры она считывает изображение JPG и сохраняет его в локальной переменной с именем l_image_clob. Программа отправляет встроенное изображение (примечание: это встроенное изображение, а не вложение электронной почты) вместе с остальной частью тела электронной почты списку пользователей. Все работает нормально.
Теперь я пытаюсь сохранить содержимое изображения JPG, хранящегося в l_image_clob, в файл JPG на сервере Windows. Следующий код создает файл с правильным именем и правильным размером, но он не читается системой. Я получаю сообщение об ошибке «Это недопустимый растровый файл», когда пытаюсь открыть его с помощью Microsoft Paint. Как мне использовать utl_file для этого?

Here's the code which creates the file that is "not a valid bitmap file"
      -- Create a file based on the content of l_image_clob
      l_image_filename := 'image_' || p_event_pkey || '_' || i ||
      '.' || l_image_ext;
      l_file_handle := utl_file.fopen(l_dirname , l_image_filename, 'wb');
      -- wb is write byte. This returns file handle
      <<inner_loop>>
      for i in 1 .. ceil( length( l_image_clob ) / chnksz )
      loop
        utl_file.put_raw( l_file_handle, 
          utl_raw.cast_to_raw( substr( l_image_clob, (i-1) * chnksz + 1, chnksz )));
        utl_file.fflush(l_file_handle);
      end loop inner_loop; 
      utl_file.fclose(l_file_handle); 

Спасибо, что посмотрели это.


person user3138025    schedule 01.02.2015    source источник


Ответы (1)


Я нашел ответ. Изображение, инициированное Apex, было закодировано в base64. Поэтому мне пришлось расшифровать его. Кто-то помог мне с процедурой, чтобы сделать это. Мой измененный код теперь выглядит так:

-- Create a file based on the content of l_image_clob
l_image_filename := 'image_' || p_event_pkey || '_' || i ||
'.' || l_image_ext;
clob_base64_to_file(l_image_clob, l_dirname, l_image_filename);

Процедура, которая вызывается, выглядит следующим образом:

create or replace procedure clob_base64_to_file( 
  p_clob        in  clob, 
  p_dir         in  varchar2, 
  p_filename    in  varchar2
  )
is
  t_buffer          varchar2(32767);
  t_pos             number := 1;
  t_len             number;
  t_fh              utl_file.file_type;
  t_size            number := nls_charset_decl_len( 32764, 
                    nls_charset_id( 'char_cs' ) );
begin
  t_fh := utl_file.fopen( p_dir, p_filename, 'wb', 32767 );
  t_len := length( p_clob );
  loop
    exit when t_pos > t_len;
    t_buffer := replace( replace( substr( p_clob, t_pos, t_size ), 
                chr(10) ), chr(13) );
    t_pos := t_pos + t_size;
    while t_pos <= t_len and mod( length( t_buffer ), 4 ) > 0
    loop
      t_buffer := t_buffer || replace( replace( substr( p_clob, t_pos, 1 ), 
                chr(10) ), chr(13) );
      t_pos := t_pos + 1;
    end loop;
    utl_file.put_raw( t_fh, 
      utl_encode.base64_decode( utl_raw.cast_to_raw( t_buffer ) ) );
  end loop;
  utl_file.fclose( t_fh );
end;

Когда я вызываю процедуру clob_base64_to_file, она декодирует изображение и создает файл на основе каталога и имени файла, которые я указываю в вызове.

person user3138025    schedule 02.02.2015