Как изменить blob oracle

Обновлено: 05.07.2024

Я пишу запрос для инструмента создания отчетов (Pentaho Report Designer), где мне нужно получить некоторые jpgs, которые хранятся в базе данных Oracle 11. Хитрость заключается в том, что в состав пробежек (сохраняемых как BLOB) входит 12-байтовый заголовок (добавленный другим приложением), который мне нужно удалить. Инструмент отчетности также требует, чтобы данные возвращались в виде данных RAW.

Я сталкиваюсь с проблемами, когда кажется, что все функции / процедуры, которые я нашел для манипулирования BLOB-объектами, имеют запретительные ограничения по размеру / длине.

Этот запрос настолько близок к работе, насколько я могу его получить, используя DBMS_LOB.SUBSTR(dbfile.filedata,2000,12):

Для изображений 5

1 ответ

Вообще говоря, невозможно изменить BLOB-объект в запросе "на лету", учитывая ORA-14553 , Переменная BLOB-объекта - это указатель на данные, но не сами данные. Вот почему такие функции, как DBMS_LOB.SUBSTR вернуть не BLOB или же CLOB , но RAW или же CHAR - поскольку данные (переменные) последних типов непосредственно доступны в оперативной памяти.

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

Очевидно, что второй способ (сохранение оригиналов) является более ресурсоемким.

Большая картина решения:

  1. Определите список BLOB-объектов, которые вы собираетесь запросить
  2. Для каждого элемента в списке создайте и сохраните модифицированный BLOB-объект (например, с урезанными 12 байтами) со ссылкой по идентификатору на оригинал.
  3. Запустить запрос, возвращающий измененные BLOB-объекты
  4. Удалить измененные BLOB-объекты (сразу же после запроса курсора используется ИЛИ по расписанию)

Это вызывает больше проблем, чем решает:

  • необходимость очистки модифицированных сгустков
  • синхронизация оригинала и модификации
  • удвоение объема хранимых данных
  • другие сюрпризы

Я думаю, что есть менее болезненное решение - написать код во внешней стороне, использующий результаты запроса, и изменить данные BLOB-объектов вне базы данных.

Для работы с данными большого объема СУБД 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-сегментах данные, свести к минимуму их дублирование, шифровать эти данные. Но эта тема выходит за рамки данного очерка.

Доброго дня. Третья часть разговора про формат XLSX подоспела. Я не случайно начал со внутреннего устройства файла. Не понимая где что находится и как выглядит, сложно понять, для чего я сделал то-то и то-то. К тому же, теперь я могу сделать несколько замечаний:

Первое. Если я не упомянул какой-то элемент, который нужен именно вам, — создайте пустой файл XLSX, сделайте нужный элемент и сохраните. Теперь вы знаете, где искать код, определяющий этот элемент.

Второе. OpenXML допускает наличие в разметке произвольного текста, если он не нарушает структуру тегов (этим мы будем очень активно пользоваться). Сейчас проиллюстрирую. Вот так делать можно:

А вот так — нельзя:


Но к делу. Строго говоря, есть два возможных случая. Либо мы имеем некий шаблон, который нам необходимо заполнить данными, либо сами вынуждены составлять файл, что называется, с нуля. Первый случай проще, второй — интереснее. Но при этом оба случая требуют от нас наличия файла-заготовки: поскольку файл .XLSX состоит не только из .XML-файлов, создать его «руками», увы, не выйдет.

Вообще методика, которой я пользуюсь, в значительной степени основывается на библиотеке Alexandria PL/SQL. Сама библиотека огромна, и если кроме как для целей, описанных ниже, она вам не нужна, то лучше имплантировать ее выборочно.

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

  1. Трансформируем файл-заготовку в BLOB;
  2. Заменяем условные метки в XML-файлах внутри него на наши данные;
  3. Сохраняем измененный BLOB как новый файл;
  4. Возвращаем измененный файл пользователю.

Трансформация файла-заготовки в BLOB

Если у нас есть в наличии некий бланк, к примеру, квитанция, в которую надо вставить ФИО абонента и сумму к оплате, то все проще некуда: берем готовую квитанцию и меняем содержимое переменных полей на специальные метки-маячки. По поводу текста этих маячков есть два основных правила — они не должны имитировать теги и вероятность совпадения в исходном тексте документа или в заменяющем тексте должна быть исчезающе малой. В остальном все зависит от вашей фантазии или привычек. Я использую что-то типа %name%. Объясню почему. Знак "%" не имитирует разметку, и вероятность того, что где-то будет слово, с двух сторон обособленное этим знаком, — мизерна.

А вот в случае, когда мы заранее не знаем, что может быть в файле на выходе, работы будет больше.

Перво-наперво рекомендую поэксплуатировать Excel и обозначить все стили ячеек, которые нам могут понадобиться (если не понадобятся — ничего страшного, это лучше, чем если чего-то не хватит). После этого лезем блокнотом в стили и записываем индексы конкретных стилей. Так, я сделал себе отдельный стиль для заголовка (серая заливка, полужирное написание и тонкие границы) и отдельный стиль для рядовой строки (без заливки, обычное написание и тонкие границы).

Далее работать придется не через Excel, а руками.

Файл sharedStrings.xml должен выглядеть примерно так:


Файл sheet1.xml (предполагая, что основным листом у нас будет первый) должен содержать следующее:


Метка %attach% расположена там, где должен находиться тег закрепления области. Метка %colsize% — там, где находится тег, указывающий ширину занятых столбцов. Это сделано для того, чтобы, допустим, в столбце ФИО ширина была соответствующей. Метка %data% будет заменена сгенерированной разметкой ячеек. Метка %filter% — на случай, если понадобится встраивать автофильтр.

Сохраняем, закрываем — болванка готова. Далее нам надо трансформировать ее в BLOB. Для этого нам понадобится библиотечная функция lib_utils.get_blob_from_file (на всякий случай напомню, что lib_utils — это функции из библиотеки по ссылке в начале поста). Функция принимает два параметра: директорию и имя файла. Поскольку это слегка неочевидно, поясню, что под директорией подразумевается оракловый объект DIRECTORY. В нашем примере назовем директорию FILE_DIR. То есть вызов будет выглядеть примерно так:

Замена меток на кастомные данные

В более простом случае с бланком квитанции (или аналогичном случае), просто используем функцию lib_utils.multi_replace. Библиотека все сделает за вас.

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


Последний тип напрямую не задействован в построении tp_table, но все равно далее будет нужен. Поясню элементы типа tp_cell.

  • address — фактический адрес ячейки. Тут надо пояснить кое-что. В комментариях к предыдущему посту выложены результаты экспериментов, показывающие, что при описании ячейки адрес вписывать необязательно. Это так. Однако, на мой взгляд, явное, как правило, лучше неявного.
  • style — ссылка на индекс стиля описываемой ячейки. Я для себя решил, что все описанные мной стили будут храниться в виде глобальных констант пакета custom_utils.
  • val — содержимое ячейки.
  • lines — флажок многострочности. Установка его значения на 2 или выше будет означать, что в содержимом ячейки подразумевается перенос, а как мы помним, для его отображения следует увеличивать высоту ячейки.


Процедура принимает следующие параметры:

  • i_content — содержимое будущего файла.
  • i_filename — имя будущего файла.
  • i_filter — флажок необходимости автофильтра.
  • i_attach — флажок необходимости закрепления области. Поскольку в моем случае требуется закрепление только первой строки, у меня генерируемый из-за этого флага код всегда будет одинаковым.

Сразу хочу кое-что пояснить. Поскольку данных в файле может быть много, работать с varchar-ообразными типами нельзя, их просто не хватит. Поэтому приходится затачивать свое решение под CLOB. В целом же, пока что ничего сверхъестественного. Но — к делу.

Управление данными Oracle CLOB и BLOB с помощью JDBC

Операции для вставки данных больших объектов (включая тип BLOB BLOB NCLOB BFILE): вставка нулевого значения-> получение столбца нулевого значения и обновление блокировки-> обновление поля большого объекта.

Основные моменты обработки данных типа LOB, полученных с помощью операции запроса: сначала используйте данные поля LOB для получения объекта InputStream или OutputStream, а затем работайте с ним по мере необходимости, если вам нужно извлечь данные, вы получите объект InputStream, если вам нужно обновить данные поля LOB, вы получите объект OutputStream ,

Программа разделена на два уровня: 1) JdbcUtil обеспечивает базовый доступ к базе данных и управление транзакциями, и 2) уровень DAO вызывает JdbcUtil для предоставления услуг DAO.

[color = brown] Таблица Content_text, содержащая данные CLOB: [/ color]

[color = brown] таблица content_bin, содержащая данные BLOB: [/ color]

------------ Вставьте данные в таблицу content_bin:

[размер = большой] [b] =============================== слой DAO ============= ========== [/ b] [/ size]
--------- Запрос к таблице content_text

-------------- Запрос к таблице content_bin

Интеллектуальная рекомендация

Поверните строку в целые числа

Тема Описание Преобразуйте строку в целое число (реализация функции integer.valueof (строка), но строка не совпадает 0), требуя функции библиотеки, которая нельзя использовать для преобразования целых.

Docker создает репликацию Redis Master-Slave

Centos установить докер быстрый старт докера Создать Dockerfile Поместите файл на сервер Linux, создайте папку / usr / docker / redis и поместите его в этот каталог Выполните следующий код в каталоге .


Установка GateOne на новом CentOS7

Установка GateOne на новом CentOS7 В последнее время исследуются такие инструменты, как WebSSH2, в настоящее время требуется встроить терминал ssh в веб-приложение и найти GateOne. GateOne - это веб-в.


Примечания к исследованию Qt4 (5), QWaitCondition of QThread Learning


Практические занятия: решения проблем системы управления обучением

Сразу после получения задания будет много трудностей и много проблем. Хорошо иметь проблему, а это значит, что вы можете получить новые знания. Неважно, есть ли проблемы, ключ в том, как их решить. пр.

Вам также может понравиться


искробезопасная практика (5) обратный индекс

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


Решение центра тяжести неправильного многоугольника

Справочник статей Во-первых, решение центра тяжести неправильных многоугольников 1.1 Метод расчета треугольника центра тяжести 1.2 Метод расчета площади треугольника 1.3 Метод расчета площади полигона.

[an error occurred while processing this directive]

Особенности работы с Blob для Oracle и Oracle Lite

[an error occurred while processing this directive](none) [an error occurred while processing this directive](none)[an error occurred while processing this directive] ::
[an error occurred while processing this directive] (none)
[an error occurred while processing this directive] ([an error occurred while processing this directive] Роман Агафонов [an error occurred while processing this directive])

[an error occurred while processing this directive](none)

Думаю, любой программист-разработчик так или иначе в своей карьере сталкивается с разработкой софта под базы данных. Многие только этим и занимаются. Самостоятельно натыкаются на подводные камни, связанные с особенностями используемой БД, и также самостоятельно пытаются их преодолеть. В принципе, стандартные средства Java избавили разработчиков от большинства проблем, и библиотека java.sql с успехом исчерпывает основную массу потребностей, но всегда есть нюансы, которые такими средствами не решаются, и, как правило, именно они больше всего интересуют программистов.

В данной статье я коснусь особенностей закачки и получения блобов в Oracle и Oracle Lite. В Oracle есть странноватая особенность, заключающаяся в том, что для того, чтобы вставить в таблицу Blob, надо сначала получить его из этой же таблицы. Соответственно, чтобы добавить новые данные в поле типа Blob, предварительно придется создать пустую запись типа Blob, а потом уже ее выдергивать из таблицы для использования в своих корыстных целях. Выглядит это примерно так:

При закачке в Blob массива данных нужно использовать именно oracle.sql.BLOB.putBytes(…) . Стандартный метод java.sql.Blob.setBytes(…) при массивах данных больших 1 мегабайта работает некорректно.

Теперь разберем Oracle Lite. Особенность заключается в том, что Oracle Lite вообще криво работает с данными типа Blob, хотя вроде бы и поддерживает оные. Как альтернативу предлагается использовать тип Long Raw, с ним проблем пока не наблюдалось — и объемы держит, и в обращении (с точки зрения программного кода) даже попроще чем Blob.

При получении данных из поля типа Long Raw java определяет их как массив байтов, но если нам нужно закачать данные, то необходимо представлять наш объект как бинарный поток. Использование метода PreparedStatement.setBytes(…) не только не совсем корректно, но даже пару раз у меня подвешивало всю базу. Для наглядности привожу кратенький пример корректного кода:

[an error occurred while processing this directive]
[an error occurred while processing this directive] (none)

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