Форум OlegON > Компьютеры и Программное обеспечение > Операционные системы и программное обеспечение > Oracle

Как выгрузить LOB построчно в соответствующие файлы : Oracle

04.05.2024 3:51


26.07.2023 20:02
OlegON
 
Итак, у меня есть табличка FINE_PHOTO с колонками id_fine_photo, body, в которых, соответственно, хранится идентификатор фотографии и сама фотография. Понадобилось выгрузить все эти фотографии из базы в файл. Oracle 19c. Сделал следующим образом:

Создал директорию, куда будут выгружаться фотографии
SQL код:
CREATE DIRECTORY OLEGON as '/mnt/photos'
Создал процедуру, которая, собственно, и выгружает данные
SQL код:
CREATE OR REPLACE PROCEDURE retrieve_lob_to_file(temp_blob in BLOBfile_path in varchar2file_name in varchar2IS 
data_buffer RAW 
(32767); 
position INTEGER := 1
filehandle utl_file.file_type
error_number NUMBER
error_message VARCHAR2(100); 
blob_length INTEGER
chunk_size BINARY_INTEGER := 32767
BEGIN 
blob_length 
:= dbms_lob.getlength(temp_blob); 
filehandle := utl_file.fopen(file_pathfile_name,'wb'1024); 
WHILE 
position blob_length LOOP 
dbms_lob
.read (temp_blobchunk_sizepositiondata_buffer); 
utl_file.put_raw (filehandledata_buffer); 
position := position chunk_size
data_buffer := null
END LOOP
utl_file.fclose(filehandle); 
EXCEPTION 
WHEN OTHERS THEN 
BEGIN 
error_number 
:= sqlcode
error_message := substr(sqlerrm ,,100); 
dbms_output.put_line('Error #: ' || error_number); 
dbms_output.put_line('Error Message: ' || error_message); 
utl_file.fclose_all
END
END

Вот код, который по заданным параметрам делает выгрузку. На всякий случай rownum оставил, поскольку у меня несколько миллионов фоток в базе и места на диске бы не хватило.
SQL код:
BEGIN
  
FOR rec IN (select id_fine_photo,body from FINE_PHOTO where rownum<10LOOP
  dbms_output
.put_line(rec.id_fine_photo);
  
sys.retrieve_lob_to_file (rec.body'OLEGON',rec.id_fine_photo||'.jpg'); 
  
END LOOP;
  
COMMIT;
END;

26.07.2023 20:04
Капитан О.
 
Для выгрузки LOB построчно в соответствующие файлы можно использовать следующий код:

Код:
sql
DECLARE
   -- Переменные для обработки LOB
   l_blob         BLOB;
   l_dest_offset  NUMBER := 1;
   l_src_offset   NUMBER := 1;
   l_lang_context NUMBER := DBMS_LOB.DEFAULT_LANG_CTX;
   l_warning      NUMBER;

   -- Переменные для итерации по таблице
   l_cursor       SYS_REFCURSOR;
   l_id           NUMBER;
   l_filename     VARCHAR2(100);
   l_directory    VARCHAR2(100) := 'DIRECTORY_NAME';

BEGIN
   -- Открытие курсора для выборки данных из таблицы Fn
   OPEN l_cursor FOR 'SELECT id, blob_column FROM Fn';

   -- Итерация по строкам таблицы
   LOOP
      -- Получение следующей строки
      FETCH l_cursor INTO l_id, l_blob;

      EXIT WHEN l_cursor%NOTFOUND;

      -- Генерация имени файла
      l_filename := 'photo_' || l_id || '.jpg';

      -- Создание дескриптора для указания пути и имени файла
      DBMS_LOB.CREATETEMPORARY(l_blob, TRUE);

      -- Открытие файла для записи
      DBMS_LOB.FILEOPEN('DATA_DIR', l_filename, 'wb');

      -- Запись данных в файл
      DBMS_LOB.LOADCLOBFROMFILE(l_blob,
                                'DATA_DIR',
                                l_filename,
                                DBMS_LOB.LOADCLOB_REPLACE);

      -- Закрытие файла
      DBMS_LOB.FILECLOSE('DATA_DIR', l_filename);

      -- Освобождение дескриптора
      DBMS_LOB.FREETEMPORARY(l_blob);

   END LOOP;

   -- Закрытие курсора
   CLOSE l_cursor;

END;
/
В данном примере предполагается, что у вас есть созданная директория с именем "DIRECTORY_NAME", в которую будут выгружаться фотографии. Также замените "Fn" на имя вашей таблицы, "id" и "blob_column" на соответствующие имена столбцов в таблице, содержащие идентификатор и LOB данные.

Обратите внимание, что код предоставлен на базе языка SQL, поэтому он может потребовать некоторых доработок в зависимости от используемой вами базы данных и среды разработки.
Часовой пояс GMT +3, время: 03:51.

Форум на базе vBulletin®
Copyright © Jelsoft Enterprises Ltd.
В случае заимствования информации гипертекстовая индексируемая ссылка на Форум обязательна.