Oracle преобразовать blob в clob

Обновлено: 05.07.2024

Я использую oracle 11g и пытаюсь узнать длину текста. Обычно я использую select length (myvar) из таблицы, но я не могу этого сделать.

Таблица, которую я хочу запросить, имеет столбец BLOB, который сохраняет символы или фотографии. Я хочу знать количество символов в моем столбце BLOB.

Я попытался преобразовать свой BLOB в символ с помощью UTL_RAW.CAST_TO_VARCHAR2(myblob) из таблицы, но эта функция работает неправильно или, может быть, я делаю ошибку.

Например: У моего BLOB есть раздел слова, когда я вижу это в базе данных в шестнадцатеричной форме, я вижу S.e.c.t.i.o.n.. Я не знаю, почему у него есть эти точки между каждой буквой. Затем я использовал этот запрос

Результат этого запроса-'S', так что это не полное слово, которое есть у моего BLOB, и когда я делаю этот запрос

в результате получается 18, а в слове Sections нет 18 символов.

Я пытался преобразовать blob в varchar, хотя я думаю, что мой лучший выбор был бы clob, потому что длина текста, который он может сохранить, больше, чем предел, который имеет varchar. Я попытался сделать это, сделав этот запрос (я не уверен, что это правильно, но это то, что я нашел в интернете)

Этот запрос также возвращает 'S'

Я надеюсь, что вы сможете помочь мне с этой проблемой. спасибо за продвинутый

4 ответа

Сначала я преобразовал BLOB изображения в CLOB, а затем преобразовал этот CLOB обратно в BLOB. Я не вижу преобразованного образа. Как я могу решить эту проблему? функция blob_to_clob : CREATE OR REPLACE FUNCTION blob_to_clob (blob_in IN BLOB) RETURN CLOB AS v_clob CLOB; v_varchar VARCHAR2(32767);.

Мне нужно преобразовать данные из CLOB в кодировку UTF8 BLOB в Oracle. Как я могу это сделать?

Для тех, кто приходит в эту тему и хочет знать, как преобразовать blob в clob. Вот пример.

Чтобы преобразовать blob в clob, попробуйте следующее:

вернет длину BLOB в байтах. Похоже, что символьные данные в вашем BLOB, вероятно, кодируются с использованием набора символов UTF-16, поэтому количество байтов, вероятно, вдвое превышает количество символов (в зависимости от используемой версии Юникода и конкретных хранимых данных некоторым символам может потребоваться 4 байта памяти, но относительно маловероятно, что вы имеете дело с любым из этих символов).

Вы можете использовать процедуру DBMS_LOB.ConvertToClob для преобразования BLOB в CLOB (хотя, поскольку это процедура, вам нужно будет вызвать ее в блоке PL/SQL). В рамках этого преобразования вам почти наверняка потребуется указать набор символов, в котором кодируются данные-я предполагаю, что ваше приложение использует набор символов UTF-16, но это всего лишь предположение.

Только преобразование в CLOB:

Вдохновленный Крейгом без ограничений по размеру.

Похожие вопросы:

У меня есть таблица со столбцом CLOB . Я хотел бы преобразовать существующие данные в тип данных BLOB . Это не удается с ORA-252858 invalid alteration of datatype . Я подумал о создании нового.

Использование Oracle Как можно преобразовать файл изображения, хранящийся в виде clob, в blob и вставить его в другую таблицу? У меня уже есть код, вытаскивающий изображение blob и отображающий его.

Могу ли я преобразовать oracle BLOB в Base64 CLOB за один раз? любить: CREATE TABLE test ( image BLOB, imageBase64 CLOB ); INSERT INTO test(image) VALUES (LOAD_FILE('/full/path/to/new/image.jpg'));.

Сначала я преобразовал BLOB изображения в CLOB, а затем преобразовал этот CLOB обратно в BLOB. Я не вижу преобразованного образа. Как я могу решить эту проблему? функция blob_to_clob : CREATE OR.

Мне нужно преобразовать данные из CLOB в кодировку UTF8 BLOB в Oracle. Как я могу это сделать?

У меня есть некоторое большое двоичное содержимое в форме hex, хранящееся в CLOB, и я хочу преобразовать его в BLOB, где код hex является фактическим двоичным байтовым кодированием: DECLARE -- This.

Я попытался использовать BLOB datatype в extractValue() для извлечения текста в указанном XPATH, но он выдает ошибку для типа данных BLOB, где он отлично работает для типа данных CLOB. Поэтому я.

У меня есть таблица в DB2 с типом столбца CLOB, я хотел бы преобразовать ее в тип BLOB. Мой подход здесь заключается в том, чтобы создать новый столбец с типом BLOB, скопировать все данные из.

У меня есть таблица в DB2 с типом столбца BLOB, я хотел бы преобразовать ее в тип CLOB. Мой подход здесь заключается в том, чтобы создать новый столбец с типом CLOB, скопировать все данные из.

Я хочу знать, что может предложить Oracle-й CLOB-й тип данных по сравнению с BLOB-м типом данных. Оба имеют ограничения хранения данных (4 GB - 1) * DB_BLOCK_SIZE. Текстовая строка длиной более 4000.

Для работы с данными большого объема СУБД Oracle предоставляет типы данных BLOB, CLOB, NCLOB и BFILE. Здесь LOB означает large object, или большой объект, и далее по тексту термины LOB и "большой объект" взаимозаменяемы. По сути, большой объект - это абстрактный тип для манипуляции данными большого объема внутри БД, а типы BLOB, CLOB, NCLOB и BFILE - его конкретные реализации.

Указанные типы данных можно использовать в СУБД Oracle для определения столбцов таблиц, атрибутов объектных типов и переменных PL/SQL.

Вот краткая характеристика этих типов:

  • BFILE (от binary file) - данные хранятся во внешнем по отношению к БД файле, а значение типа BFILE содержит указатель на файл; данные считаются двоичными.
  • BLOB (от binary large object) - данные хранятся в базе данных в отдельном сегменте * , а значение типа BLOB содержит указатель на них (LOB locator); данные считаются двоичными.
  • CLOB (от character large object) - данные хранятся в базе данных в отдельном сегменте * , а значение типа CLOB содержит указатель на них (LOB locator); данные интерпретируются как текст в кодировке базы данных (database character set).
  • NCLOB (от national character large object) - данные хранятся в базе данных в отдельном сегменте * , а значение типа CLOB содержит указатель на них (LOB locator); данные интерпретируются как текст в национальной кодировке (national character set)

* По умолчанию LOB'ы размером до 4000 байт хранятся непосредственно в строках таблицы (в табличном сегменте), а LOB'ы большего размера - в отдельном сегменте (возможно, в отдельном табличном пространстве). Это поведение регулируется опцией ENABLE|DISABLE STORAGE IN ROW команд CREATE TABLE и ALTER TABLE .

Итак, по месту хранения LOB'ы делятся на

  • внутренние (BLOB, CLOB, NCLOB), данные которых хранятся в БД, и
  • внешние (BFILE), данные которых хранятся в файлах операционной системы,

а по содержанию на

  • двоичные (BFILE и BLOB), для хранения данных в двоичных форматах, например, MP3, JPG, объектный код программ, и
  • текстовые (CLOB и NCLOB), для хранения данных в текстовых форматах, таких как XML, HTML, JSON, обычный текст.

Oracle 11g, согласно документации, работает с внутренними LOB'ами размером до 2 32 -1 байт и с BFILE файлами размером до 2 64 -1 байт.

Для работы с LOB'ами cоздам таблицу со столбцами соответствующих типов:

Вместе с таблицей были созданы сегменты для хранения больших объектов:

Для столбца типа BFILE отдельный сегмент не создан - ведь данные этого типа хранятся во внешних файлах.

Значение типа LOB может быть

  • NULL - неинициализировано, не содержит указателя на LOB,
  • пустым (empty) - указатель на LOB указывает в никуда,
  • непустым - указатель на LOB указывает на данные LOB'а.

Пустые LOB значения создаются функциями EMPTY_CLOB и EMPTY_BLOB :

Последний запрос демонстрирует два способа проверить, является ли LOB пустым. Запрос использует пакет DBMS_LOB , содержащий процедуры и функции для работы с LOB'ами.

Начиная с версии Oracle 9i в SQL и PL/SQL поддерживается неявная конвертация между (N)CLOB и VARCHAR2, что позволяет манипулировать значениями в (N)CLOB столбцах и переменных так, как будто это значения типа VARCHAR2:

Как видим, функции и операторы, работающие с VARCHAR2, перегружены для типа (N)CLOB! При этом преодолеваются ограничения в 4000 символов, свойственные SQL типу VARCHAR2:

А вот операторы сравнения для (N)CLOB работают только в PL/SQL и не работают в SQL:

Выше я воспользовался функциями TO_NCLOB и TO_CLOB для явной конвертации значений VARCHAR2 в значения (N)CLOB. В следующей таблице представлены все функции для конвертации в LOB типы и обратно:

ФункцияГде работает
TO_CLOB(character_data) SQL и PL/SQL
TO_BLOB(raw_data) SQL и PL/SQL
TO_LOB(long_data) SQL and PL/SQL
TO_NCLOB(character_data) SQL и PL/SQL
TO_RAW(blob_data) только PL/SQL

Как видим, функция TO_RAW недоступна в SQL и, отсюда, возможности конвертации между BLOB и RAW в SQL ограничены. Например:

Зато в PL/SQL работают явная и неявная конвертации между BLOB и RAW:

Рассмотренные возможности по работе со значениями LOB как с VARCHAR2 получили название SQL семантика для LOB'ов (SQL semаntics for LOBs). С их использованием связаны некоторые ограничения, как мы увидим ниже.

С точки зрения PL/SQL большие объекты делятся на:

  • временные (temporary), время жизни которых не превышает сеанса работы с СУБД,
  • постоянные (persistent), которые хранятся в базе данных или во внешнем файле.
  • создаются либо с помощью DBMS_LOB.CREATETEMPORARY , либо простым присваиванием значения LOB переменной в PL/SQL коде,
  • располагаются на диске во временном табличном пространстве (temporary tablespace),
  • могут быть проверены с помощью DBMS_LOB.ISTEMPORARY ,
  • освобождаются с помощью DBMS_LOB.FREETEMPORARY , что приводит к инвалидированию указателя на LOB,
  • в отличие от постоянных, изменяются без создания записей в журнале БД (logging) и не контролируются транзакциями,
  • могут быть скопированы в постоянные LOB'ы c помощью DBMS_LOB.COPY .

В вышеприведенных примерах с PL/SQL мы имели дело с временными LOB'ами.

Для работы с постоянными LOB'ами в PL/SQL нужно сначала получить указатель на LOB, а затем с его помощью извлекать или изменять данные, используя пакет DBMS_LOB . Следующий пример демонстрирует получение постоянного LOB'а и его потерю(!) при попытке изменить его значение простым присваиванием:

Дело в том, что SQL семантика для LOB'ов всегда порождает временные LOB'ы - это и есть то ограничение, о котором я упоминал выше. Неявное приведение VARCHAR2 к LOB (строка 7) или функция, перегруженная для (N)CLOB (строка 14), дают нам временные LOB'ы. Как только переменной PL/SQL, указывающей на постоянный LOB, присваивается временный LOB, переменная начинает указывать на временный LOB. А связь переменной с постоянным LOB'ом утрачивается.

Значение временного LOB'а можно сохранить в БД - и тем самым сделать постоянным - либо с помощью SQL либо, как уже упоминалось, с помощью DBMS_LOB.COPY . Продемонстрирую обе возможности:

Обратите внимание, что процедура DBMS_LOB.COPY заменила в постоянном NCLOB c3 только фрагмент, равный по размеру значению исходного NCLOB'а c2 . Как вариант, можно было перед копированием очистить LOB назначения с помощью DBMS_LOB.ERASE .

Изменения внутренних постоянных LOB'ов (в отличие от внешних или временных) в СУБД Oracle подчиняются транзакциям. Убедимся в этом, отменив только что сделанные изменения:

Типичный алгоритм для чтения или изменения постоянного LOB'а с помощью PL/SQL таков:

  1. Извлечь указатель на LOB из столбца таблицы с помощью SELECT .
  2. Открыть большой объект с помощью DBMS_LOB.OPEN .
  3. Получить оптимальный размер фрагмента для чтения (записи) LOB с помощью DBMS_LOB.GETCHUNKSIZE
  4. Получить размер LOB'а в байтах (для BLOB и BFILE) или символах (для CLOB и NCLOB) с помощью DBMS_LOB.GETLENGTH .
  5. Многократно вызывать DBMS_LOB.READ для чтения последовательных фрагментов LOB'а, пока не будут извлечены все данные
    ИЛИ
    многократно вызывать DBMS_LOB.WRITE , со смещением, или DBMS_LOB.WRITEAPPEND или иные процедуры DBMS_LOB для записи фрагментов данных.
  6. Закрыть LOB с помощью DBMS_LOB.CLOSE .

В предыдущем примере с DBMS_LOB.COPY я не открывал и не закрывал постоянный LOB при помощи DBMS_LOB.OPEN и DBMS_LOB.CLOSE , однако, это стоит делать для улучшения производительности при изменениях больших объектов.

Приведу пример выгрузки данных из постоянного CLOB'а во внешний файл. Для доступа к внешним файлам потребуется создать директорию, например:

Следующий код выгружает содержимое столбца lobs_tab.clob_col в файл clob_col1.txt , используя пакет DBMS_LOB для чтения CLOB и пакет UTL_FILE для записи во внешний файл:

Альтернативно, можно выгрузить CLOB во внешний файл, пользуясь SQL семантикой для LOB и не прибегая к DBMS_LOB :

Для обратной операции - загрузки содержимого файла в LOB - также можно воспользоваться пакетами UTL_FILE и DBMS_LOB , циклически читая данные из файла и записывая в LOB. Но интереснее сделать это с помощью типа данных BFILE.

Тип данных BFILE содержит указатель на внешний файл, который

  • состоит из двух частей: имя директории и имя файла,
  • создается с помощью функции BFILENAME , например, BFILENMAE('FILES_DIR', 'novel.txt') ,
  • может указывать на несуществующий файл.

Пакет DBMS_LOB позволяет читать содержимое BFILE, но не изменять его. Чтение из BFILE возвращает двоичные данные как тип данных RAW. Для преобразования в VARCHAR2, при необходимости, используется функция UTL_RAW.CAST_TO_VARCHAR2 .

Пример чтения BFILE и записи во временный BLOB:

В примере BFILE открывается и закрывается с помощью OPEN и CLOSE , аналогично внутренним LOB'ам. Также, пакет DBMS_LOB содержит несколько процедур и функций специально для работы с объектами BFILE:

Процедура / ФункцияЧто делает
FILEGETNAME возвращает имя директории и файла BFILE
FILEEXISTS проверяет, что файл BFILE существует
FILEOPEN открывает файл BFILE
FILEISOPEN проверяет, что файл BFILE открыт
FILECLOSE закрывает файл BFILE
FILECLOSEALL закрывает все открытые в сеансе файлы BFILE

Вместо чтения BFILE по частям пакет DBMS_LOB позволяет

  • с помощью LOADCLOBFROMFILE загрузить содержимое BFILE в CLOB, указав, какую кодировку (набор символов) имеет содержимое,
  • с помощью LOADBLOBFROMFILE загрузить содержимое BFILE в BLOB.

Пример загрузки текстового файла во временный CLOB (аналогично можно загрузить и в постоянный CLOB):

Значения src_offset и dest_offset отличаются, поскольку первое, для BFILE, выражено в байтах, а второе, для CLOB, выражено в символах. В файле и CLOB'е имеются девять двухбайтовых русских букв - напомню, их содержимое начинается с " привет, мир ".

Приведу неполный список процедур и функций DBMS_LOB для чтения, анализа и изменения значений BLOB, CLOB и NCLOB:

Процедура / ФункцияЧто делает
APPEND добавляет один LOB в конец другого
COPY копирует все или часть содержимого LOB'а в другой LOB
ERASE удаляет все или часть содержимого LOB'а
GETLENGTH возвращает размер LOB'а
INSTR ищет "подстроку" в LOB'е
ISOPEN проверяет, открыт ли LOB
ISTEMPORARY проверяет, временный ли LOB
READ читает данные LOB'а
SUBSTR получает "подстроку" из LOB'а
TRIM сокращает размер LOB'а до указанного
WRITE записывает данные в LOB
WRITEAPPEND записывает данные в конец LOB'а

Следующий эксперимент покажет разницу между внутренними и внешними постоянными LOB'ами. Помещу в поле bfile_col таблицы lobs_tab объект BFILE и скопирую единственную строку таблицы во вторую строку:

Команда INSERT привела к тому, что значения bfile_col в обеих строках связаны с одним и тем же внешним файлом, и его изменение отразится на обоих значениях.

А вот значения столбцов clob_col , nclob_col и blob_col для строк 1 и 2 стали независимы - не только указатели на LOB, но и данные внутренних LOB'ов в LOB-сегментах были скопированы. Продемонстрирую их независимость, изменив значения clob_col и nclob_col для строки 2:

Аналогично, при присваивании BLOB и (N)CLOB переменных в PL/SQL мы получаем независимые копии LOB'ов:

Итак, мы на примерах рассмотрели работу с большими объектами в SQL и PL/SQL. Работа с большими объектами имеет и другой аспект - это технология SecureFiles, позволяющая, в частности, сжимать хранимые в LOB-сегментах данные, свести к минимуму их дублирование, шифровать эти данные. Но эта тема выходит за рамки данного очерка.

Могу ли я конвертировать Oracle BLOB в Base64 CLOB за один раз?

Я знаю, что могу добавить функции/Хранимый процесс для выполнения работы. Аспект производительности очень важен, поэтому я спрашиваю, есть ли способ преодолеть ограничение 32 КБ, непосредственно помещая данные в CLOB.

При условии, что хранимые процедуры будут, несмотря на это, жизнеспособной альтернативой для вас, вот одно из возможных решений вашей проблемы .

Во-первых, давайте превратим функцию Nice base64encode() Тима Холла в процедуру .

«Хитрость» заключается в том, чтобы напрямую использовать постоянные локаторы больших объектов в вызовах процедур/функций. Почему "настойчивый"? Потому что, если вы создаете функцию, которая возвращает LOB, то в фоновом режиме создается временный LOB, что означает некоторое использование диска/памяти TEMP и копирование содержимого LOB. Для больших объектов это может означать снижение производительности. Чтобы удовлетворить ваши требования сделать это максимально эффективным, вы должны избегать использования пространства TEMP. Следовательно, для этого подхода необходимо использовать хранимую процедуру вместо функции.

Тогда, конечно, процедура должна быть снабжена постоянными локаторами LOB. Вы должны сделать это снова с помощью хранимой процедуры, где вы, например, сначала вставьте в таблицу пустой большой объект (эффективно создавая новый локатор больших объектов), а затем передайте этот недавно созданный локатор больших объектов в подпрограмму кодирования base64 .

Примечание: Конечно, если вы кодируете base64 только небольшие файлы (фактический размер зависит от ваших настроек PGA, я думаю ; вопрос для администратора баз данных, это так), то подход на основе функций может быть одинаково эффективен, чем этот основанный на процедуре. Кодирование Base64 файла размером 200 МБ на моем ноутбуке заняло 55 секунд с подходом функция + обновление, 14 секунд с подходом процедуры. Не совсем демон скорости, так что выбирайте то, что соответствует вашим потребностям.

Примечание: Я полагаю, что этот основанный на процедурах подход может быть еще более ускорен путем чтения файла в ячейки памяти в цикле, кодирования base64 кусочками другой ячейки памяти и добавления их обоих в целевые постоянные большие объекты. Таким образом, вы должны упростить рабочую нагрузку, избегая повторного чтения полного содержимого объекта test.image с помощью процедуры base64encode() .

Эта функция получила отсюда должна сделать работу.

Тогда обновление может выглядеть как

Обратите внимание, что, возможно, функцию следует оптимизировать с помощью функции DBMS_LOB.APPEND вместо этого оператора конкатенации. Попробуйте, если у вас есть проблемы с производительностью.

Я решил эту проблему на работе с помощью хранимой процедуры Java. В таком подходе нет разделения на части/заражения VARCHAR2, поскольку возможность кодирования/декодирования base64 изначально встроена в Java, просто написание функции Oracle, которая тонко оборачивает метод Java, хорошо работает и обеспечивает высокую производительность, поскольку Вы выполнили это несколько раз, JSM HotSpot компилирует процесс Java в низкоуровневый код (высокая производительность, как в хранимой функции Си). Я отредактирую этот ответ позже и добавлю детали об этом коде Java.

Но если сделать шаг назад, задайте вопрос, почему вы храните эти данные как в двоичном формате, так и в кодировке base64 (CLOB)? Это потому, что у вас есть клиенты, которые хотят использовать данные в последнем формате? Я действительно предпочел бы хранить только формат BLOB. Одна из причин этого заключается в том, что версия в кодировке base64 может быть в два раза больше исходного двоичного BLOB, поэтому хранение их обоих означает, возможно, в 3 раза больше памяти.

Одно из решений, которое я реализовал на работе, - создать собственную хранимую функцию Java base64_encode() , которая кодирует двоичный код -> base64, а затем использовать эту функцию для кодирования base64 на лету во время запроса (это не дорого). Со стороны приложения/клиента вы бы запросили что-то вроде SELECT base64_encode(image) FROM test WHERE .

Если код приложения не может быть затронут (например, приложение COTS), или если ваши разработчики не в восторге от использования функции, вы можете абстрагироваться для них (так как вы используете 11g +), используя столбец VIRTUAL (вычисляемый) на таблица, которая содержит вычисленную base64_encode(image) . Он будет функционировать как представление в том смысле, что он не будет физически хранить закодированные CLOB, но будет генерировать их во время запроса. Ни одному клиенту они не смогут сказать, что не читают физический столбец. Другое преимущество заключается в том, что если вы когда-нибудь обновите jpg (BLOB), виртуальный CLOB будет немедленно и автоматически обновлен. Если вам когда-либо понадобится вставить/обновить/удалить огромную партию больших двоичных объектов, вы сэкономите 66% объема повторного выполнения/архивного журнала, не обрабатывая все большие двоичные объекты.

Наконец, для повышения производительности убедитесь, что вы используете SecureFile LOB (как для BLOB, так и для CLOB). Они действительно намного быстрее и лучше почти во всех отношениях.

UPDATE- Я нашел свой код, по крайней мере, версию, которая использует хранимую процедуру Java, чтобы сделать обратное (преобразование закодированного в base64 CLOB в его двоичную версию BLOB). Было бы не так сложно написать обратное.

могу ли я преобразовать Oracle BLOB в Base64 CLOB за один раз?

Я знаю, что могу добавить функции / сохраненный proc для выполнения работы. Аспект производительности очень важен, поэтому я спрашиваю, есть ли способ преодолеть ограничение 32K, напрямую вставляя данные в CLOB.

при условии, что сохраненные процессы будут, несмотря на жизнеспособную альтернативу для вас, вот одно возможное решение вашей проблемы .

во-первых, давайте сделаем это красиво

эта функция есть отсюда должен делать свою работу.

тогда обновление может выглядеть как

обратите внимание, что, возможно, функция должна быть оптимизирована с помощью функции DBMS_LOB.Добавьте вместо этого оператор конкатенации. Попробуйте это, если у вас есть проблемы с производительностью.

Я решил эту же проблему на работе, используя хранимую процедуру Java. В таком подходе нет чанкинга/контатенации VARCHAR2s, поскольку возможность кодирования / декодирования base64 изначально встроена в Java, просто написание функции Oracle, которая тонко обертывает метод Java, работает хорошо и является высокопроизводительной, так как как только вы выполнили его несколько раз, HotSpot JVM компилирует Java proc в низкоуровневый код (высокая производительность так же, как и хранимая функция C). Я буду редактировать этот ответ позже и добавьте сведения об этом коде Java.

но чтобы отступить всего на один шаг, вопрос, почему вы храните эти данные как BLOB и base64 закодированы (CLOB)? это потому что у вас есть клиенты, которые хотят использовать данные в последнем формате? Я бы предпочел хранить только формат BLOB. Одна из причин заключается в том, что кодированная версия base64 может быть вдвое больше размера исходного двоичного BLOB, поэтому сохранение их обоих означает, возможно, 3x место хранения.

одно решение, которое я реализовал на работе, чтобы создать свою собственную сохраненную функцию Java base64_encode() который кодирует binary --> base64, а затем использует эту функцию для кодирования base64 на лету во время запроса (это не дорого). Со стороны приложения / клиента вы запросите что-то вроде SELECT base64_encode(image) FROM test WHERE .

если код приложения нельзя коснуться (т. е. приложение COTS) или если ваши разработчики не в восторге от использования функции, вы можете абстрагировать это для них (так как вы используете 11g+), используя виртуальный (вычисляемый) столбец в таблице, который содержит вычисляемый base64_encode(image) . Он будет функционировать как представление, поскольку физически не будет хранить закодированные Клобы, а будет генерировать их во время запроса. Для любого клиента они не смогут сказать, что не читают физическую колонку. Другое преимущество заключается в том, что если вы когда-либо обновляете jpg (BLOB), виртуальный CLOB немедленно и автоматически обновляется. Если вам когда-либо нужно вставить/обновить / удалить огромный пакет из BLOBs вы сэкономите 66% объема redo / archivelog от необходимости обрабатывать все CLOBs.

наконец, для производительности убедитесь, что вы используете Securefile LOBs (как для BLOBs, так и для CLOBs). Они действительно намного быстрее и лучше почти во всех отношениях.

обновление - я нашел свой код, по крайней мере, версию, которая использует хранимую процедуру Java, чтобы сделать обратное (преобразование кодированного CLOB base64 в его двоичную версию BLOB). Оно не будет трудно написать обратное.

самый простой способ, который я нашел, который работает со специальными символами (в вашем случае у вас нет этой проблемы), использует dbms_lob.конвертоклоб.


Всем привет!
Сегодня расскажу о небольшой доработке Oracle BI Publisher,
которая позволит выгружать сохраненные в БД файлы в виде BLOB.

Далее подробнее:

Созданные Java классы (файл oracle\xdo\servlet\XxBlobExportFilter.java):

Включение созданного фильтра сервлетов в развернутое веб-приложение BIPublisher
1) Найдите ear-файл приложения в каталоге Middleware\Oracle_BI1\bifoundation\jee
2) Переименуйте xmlpserver.ear в xmlpserver.ear.original
3) Создайте новую папку xmlpserver.ear. Разархивируйте в нее содержимое файла xmlpserver.ear.original.


4) В каталоге xmlpserver.ear переименуйте файл xmlpserver.war в xmlpserver.war.original.
5) Создайте новую папку xmlpserver.war. Разархивируйте в нее содержимое файла xmlpserver.war.original.


6) Перейдите в каталог WEB-INF в папке xmlpserver.war.
7) Создайте новую папку classes и скопируйте в нее скомпилированные классы, включая их полный путь: oracle.xdo.servlet



9) Также необходимо обновить инсталляцию приложения bipublisher (xmlpserver) в консоли WebLogic.







Работы в БД

1) Создадим таблицу в БД, хранящую BLOB-файлы.

2) Создадим функцию по base54-преобразованию BLOB в CLOB

Создание отчета в BIPublisher

1) Создадим новую модель данных с набором данных типа SQl Query
Альясы столбцов должны быть следующими: BLOB_DATA и BLOB_NAME (java-код фильтра будет искать именно эти теги в сформированном XML-файле).


2) Очевидно, что не всегда требуется включение фильтра. Поэтому для отчетов, выгружающих BLOB-файлы из БД, мы создадим признак с тегом G_BLOB_EXPORT. Значение TRUE будет являться сигналом для работы фильтра.



3) Также нам следует явно задать имя группы в формируемом XML с данными, которая будет содержать выгружаемые BLOB (по сути - CLOB) файлы. Для этого перейдите на вкладку Structure модели данных и задайте имя группы равным G_BLOB


Читайте также: