Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Clob to file using PL/SQL  [new]
kamolsan
Member

Откуда:
Сообщений: 364
Здравствуйте!
Ситуация:
В книге Том Кайта «Oracle для профессионалов»
Написана что Clob и Blob данные можно загружать но нельзя выгружать в файл с помощью PL/SQL. Для этой ситуации используются другие языки как C или Java.
Запись значений объекта типа BLOB/CLOB на диск.

Этой возможности в пакете DBMS_LOB недостает. Пакет предоставляет средства
загрузки больших объектов из файлов, но не создания файла, содержащего большой
объект. Решение этой проблемы предложено в главах 18 и 19. Там приведен код на язы-
ке С и Java для внешней процедуры, записывающей значение столбца типа BLOB, CLOB
в базе данных или временного большого объекта в файл файловой системы сервера. Обе
реализации выполняют одну и ту же функцию, просто использованы разные языки.
Применяйте ту из них, которая больше подходит для вашего сервера (например, если
на сервере не установлена поддержка языка Java, но есть прекомпилятор Pro*C и ком-
пилятор языка С, то внешняя процедура на языке С подойдет больше).
Вопрос:
1. Эти информация относима и к Oracle9i?
2. Если есть возможность, приведите пример выгрузки clob’а в файл на PL/SQL’е?

Заранее спасибо!
23 фев 06, 11:17    [2384832]     Ответить | Цитировать Сообщить модератору
 Re: Clob to file using PL/SQL  [new]
Колобок
Member

Откуда:
Сообщений: 122
utl_file

dbms_lob.read
utl_file.put
23 фев 06, 11:30    [2384854]     Ответить | Цитировать Сообщить модератору
 Re: Clob to file using PL/SQL  [new]
kamolsan
Member

Откуда:
Сообщений: 364
Колобок
utl_file

dbms_lob.read
utl_file.put

Нашёл статью

классный пример Дениса Попова!


Но мне бы хотелось пример на PL/SQL’е

С

UTL_FILE.PUT (file IN FILE_TYPE, buffer IN VARCHAR2);

придётся построчно добавлять в файл?

Не могли бы ВЫ привести пример?
23 фев 06, 13:13    [2385065]     Ответить | Цитировать Сообщить модератору
 Re: Clob to file using PL/SQL  [new]
Denis Popov
Member

Откуда: Санкт-Петербург
Сообщений: 7856
C BLOB'ами так:
create or replace directory TMP as '/home/oracle/tmp';

declare
  v_file_name varchar2(64) := 'cat.bmp';

  v_blob blob;

  in_file bfile;
  out_file utl_file.file_type;
  v_buffer raw (32767);
  v_amount binary_integer := 32767;
  v_pos integer := 1;
  v_blob_len integer;
begin
  dbms_lob.createTemporary(v_blob, true, dbms_lob.SESSION);

  -- Читаем файл.
  in_file := bFileName('TMP', v_file_name);
  dbms_lob.fileOpen(in_file);
  dbms_lob.loadFromFile(v_blob, in_file, dbms_lob.getLength(in_file));
  dbms_lob.fileClose(in_file);
--  dbms_output.put_line('lob length = '||dbms_lob.getLength (v_blob)||';');

  -- Пишем в новый файл
  out_file := utl_file.fopen ('TMP', 'new_'||v_file_name, 'w', 32760);
  v_blob_len := dbms_lob.getLength (v_blob);
  while v_pos < v_blob_len loop
    dbms_lob.read (v_blob, v_amount, v_pos, v_buffer);
--    dbms_output.put_line('raw length = '||lengthb(utl_raw.cast_to_varchar2(v_buffer))||';');
    utl_file.put_raw (out_file, v_buffer, true);
    v_pos := v_pos + v_amount;
  end loop;
  utl_file.fClose(out_file);
exception when others then
  if utl_file.is_open(out_file) then
    utl_file.fClose(out_file);
  end if;
  raise;
end;
/

23 фев 06, 14:34    [2385255]     Ответить | Цитировать Сообщить модератору
 Re: Clob to file using PL/SQL  [new]
kamolsan
Member

Откуда:
Сообщений: 364
Спасибо!
Денис, спасибо за пример с blob ' ом!
24 фев 06, 07:56    [2386420]     Ответить | Цитировать Сообщить модератору
 Re: Clob to file using PL/SQL  [new]
ice_79
Member

Откуда: Тула
Сообщений: 35
Попробовал выполнить приведенный код для произвольных файлов (Oracle 9i release 9.2.0.1):

1) Если файл содержит строку, длина которой превышает указанную максимальную при открытии (4-ый параметр utl_file.fopen), то вылетает ошибка "ORA-29285: ошибка при записи файла".

2) Если взять текстовый файл, где длина строки меньше указанной максимальной, то удваиваются переводы строк (на каждый перевод добавляется еще символ перевода строки). И в конец файла дописывается перевод строки+возврат каретки.

Думаю, что для записи произвольных двоичных файлов UTL_FILE вообще нельзя использовать, а для текстовых приведенный код надо будет дорабатывать.

Поправьте меня, если я ошибся.
1 мар 06, 13:04    [2403474]     Ответить | Цитировать Сообщить модератору
 Re: Clob to file using PL/SQL  [new]
artemisin
Member

Откуда:
Сообщений: 550
про двоичные ничего сказать не могу, а вот в принципе по проблеме есть свои 5 копеек:
несколько раз сталкивался с проблемой, когда необходимо было выгружать из таблицы LOB-поля для дальнейшей их загрузки в другую БД. ну на тестовой БД играемся, а при сборке патча на продакшн выливаем новые данные в обчный скрипт. Так вот написать свою приблуду для BLOB->VARCHAR2 а потом VARCHAR2->BLOB на PL/SQL труда особого не составляет. Юзать DBMS_LOB, UTL_RAW.
1 мар 06, 13:11    [2403521]     Ответить | Цитировать Сообщить модератору
 Re: Clob to file using PL/SQL  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15424
автор
..в файл файловой системы сервера..

В большинстве случаев использовать сторону сервера для выгрузки лобов в файлы (мягко говоря) нерационально. Следом (обычно) надо решать задачу
доставки того файла клиенту..
Нормальная практика - выгружать лобы на диск клиента, но уж, без pl/sql - а средствами клиента же (OCI)
1 мар 06, 13:16    [2403554]     Ответить | Цитировать Сообщить модератору
 Re: Clob to file using PL/SQL  [new]
AlexOI
Member

Откуда: Санкт-Петербург
Сообщений: 161
ice_79
Попробовал выполнить приведенный код для произвольных файлов (Oracle 9i release 9.2.0.1):

1) Если файл содержит строку, длина которой превышает указанную максимальную при открытии (4-ый параметр utl_file.fopen), то вылетает ошибка "ORA-29285: ошибка при записи файла".

2) Если взять текстовый файл, где длина строки меньше указанной максимальной, то удваиваются переводы строк (на каждый перевод добавляется еще символ перевода строки). И в конец файла дописывается перевод строки+возврат каретки.

Думаю, что для записи произвольных двоичных файлов UTL_FILE вообще нельзя использовать, а для текстовых приведенный код надо будет дорабатывать.

Поправьте меня, если я ошибся.


Начиная с 10-й версии этой проблемы нет. В предыдущих версиях это можно решить только в ограниченных случаях. Когда я делал выгрузку DBF-файлов формируемых в Oracle, то в биты признака удаления строки писал chr(10) и периодически (после каждой строки) выполнял UTL_FILE.FFLUSH. Таким образом удавалось выгружать файлы любого размера. После этого с ними были сложности при чтении их MS ACCESS. Другие продукты работали с ними без проблем. Разумеется такой вариант очень ограничен в применении
1 мар 06, 16:38    [2404956]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: Clob to file using PL/SQL  [new]
fuy
Member

Откуда:
Сообщений: 13
столкнулся с вышеописанной проблемой.
есть большой .xml, записанный в clob, и когда я пытаюсь записать его в файл (с помощью dbms_lob и utl_file), то возникает такая же проблема:
"Если файл содержит строку, длина которой превышает указанную максимальную при открытии (4-ый параметр utl_file.fopen), то вылетает ошибка "ORA-29285: ошибка записи файла", несмотря на то, что я использую fflush в loop (как указал AlexOI).
Я подозреваю, что дело мб в том, первая же строка превышает допустимый размер (но я не уверен). Что посоветуете попробовать/проверить?
И еще вопрос заодно: если текстовая информация записана в поле типа blob, то как можно получить ее назад в текстовом виде?
Заранее спасибо!
26 июл 07, 18:35    [4441939]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: Clob to file using PL/SQL  [new]
clob2file
Guest
Вот нормальное работающее решение:
автор
begin
...
dbms_xslprocessor.clob2file(v_lob,'DIR',file_name,csid);
end;
/

где csid - это кодировка, если 0, то в кодировке БД.
Если в другой, то так например:
dbms_xslprocessor.clob2file(v_lob,'DIR',file_name,NLS_CHARSET_ID('RU8PC866'));
...


Решил здесь написать, потому что при поиске в Google фразы CLOB to file , первой же ссылкой показывает эту тему.
На дворе уже 12 версия на подходе, а dbms_xslprocessor.clob2file уже в 10-ке появилось.
А тут какую-то хе...ю обсуждают с ииспользованием UTL_FILE.
28 сен 12, 15:13    [13239273]     Ответить | Цитировать Сообщить модератору
 Re: Clob to file using PL/SQL  [new]
-2-
Member

Откуда:
Сообщений: 13727
clob2file
Решил здесь написать, потому что при поиске в Google фразы CLOB to file , первой же ссылкой показывает эту тему.
За шесть лет гугл улучшил алгоритмы поиска?
28 сен 12, 15:16    [13239298]     Ответить | Цитировать Сообщить модератору
 Re: Clob to file using PL/SQL  [new]
clob2file
Guest
-2-
clob2file
Решил здесь написать, потому что при поиске в Google фразы CLOB to file , первой же ссылкой показывает эту тему.
За шесть лет гугл улучшил алгоритмы поиска?


Ну, возможно они что-то улучшили.

А мне раньше не было надобности выкладывать CLOB-ы в файлы отдельными файлами, построчно. Более тщательное исследование гугла помогло найти более изящное и быстрое решение. Написал здесь - чтобы другие не пытались реализовывать что-то на Java или использовать UTL_FILE.
28 сен 12, 15:26    [13239394]     Ответить | Цитировать Сообщить модератору
 Re: Clob to file using PL/SQL  [new]
sworn
Member

Откуда: Point of no return
Сообщений: 127
clob2file
выкладывать CLOB-ы в файлы отдельными файлами, построчно

clob2file
чтобы другие не пытались реализовывать что-то на Java или использовать UTL_FILE.

а как быть с платформозависимостью символов новой строки?
28 сен 12, 15:38    [13239504]     Ответить | Цитировать Сообщить модератору
 Re: Clob to file using PL/SQL  [new]
clob2file
Guest
sworn
clob2file
выкладывать CLOB-ы в файлы отдельными файлами, построчно

clob2file
чтобы другие не пытались реализовывать что-то на Java или использовать UTL_FILE.

а как быть с платформозависимостью символов новой строки?


А какие там проблемы?
28 сен 12, 15:51    [13239608]     Ответить | Цитировать Сообщить модератору
 Re: Clob to file using PL/SQL  [new]
sworn
Member

Откуда: Point of no return
Сообщений: 127
clob2file
А какие там проблемы?

У нас к примеру CLOB-ы принято формировать с новой строкой chr(10), платформа unix => родной line терминатор тоже chr(10) , все казалось бы сходится, но вот пользователям в ряде случаев надо виндовые chr(13)||chr(10), приходится построчно сваливать clob в файл с параметризированной подстановкой символов новой строки.
28 сен 12, 16:00    [13239652]     Ответить | Цитировать Сообщить модератору
 Re: Clob to file using PL/SQL  [new]
clob2file
Guest
sworn
clob2file
А какие там проблемы?

У нас к примеру CLOB-ы принято формировать с новой строкой chr(10), платформа unix => родной line терминатор тоже chr(10) , все казалось бы сходится, но вот пользователям в ряде случаев надо виндовые chr(13)||chr(10), приходится построчно сваливать clob в файл с параметризированной подстановкой символов новой строки.


Ну это как-бы уже другая задача. Я так понимаю задача стоит изначально в чистом виде - это как CLOB записать в файл 1 к 1.
Ваша же задача другая и в общем случае - это трансформация содержимого CLOB.

Почему бы вам перед выгрузкой не сделать с CLOB все необходимые манипуляции и потом выгрузить способом мною предложенным. Например так:
автор
dbms_xslprocessor.clob2file(REPLACE(v_lob,chr(10),chr(10)||chr(13),.........
28 сен 12, 16:15    [13239740]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить