2015-10-16 1 views
7

У меня есть таблица в оракуле с столбцом BLOB, который может хранить XML-файлы, а также XMLs zipped. Это требования заказчика и не могут быть изменены. Таблицы будут созданы, и я должен прочитать и работать с некоторой информацией внутри BLOBs.Вставить тестовую строку BLOB больше 2000 или 4000 байт

Я исследовал, и любые из нечетких решений были ясны или работали для меня.

Проблема я столкнулся в том, что к INSERTXML равнинных данных размером более 2000 bytes с utl_raw.cast_to_raw использованием DBeaver в качестве менеджера баз данных. Я получил сообщение:

SQL Error [6502] [65000]: ORA-06502: PL/SQL: numeric or value error: raw variable length too long ORA-06512: at "SYS.UTL_RAW", line 224 
java.sql.SQLException: ORA-06502: PL/SQL: numeric or value error: raw variable length too long 
ORA-06512: at "SYS.UTL_RAW", line 224 

Проблемы

  1. Я исследовал и UTL_RAW не может быть больше, чем 2000 bytes
  2. кажется, что есть еще одно ограничение 4000 bytes для BLOBs в Oracle

Что я могу сделать для этих случаев?

+0

Что вы хотите сделать? Загрузите zip-файл в колонку blob? –

+0

Спасибо за ваш интерес. Проблема, с которой я сталкиваюсь, заключается в том, что для INSERT XML plain data больше 2000 байт с utl_raw.cast_to_raw – Weslor

+1

Что вы используете для вставки данных. Приложение SQPLUS или java? –

ответ

5

Для начала вам нужно понять, что такое LOB. Это «большие данные», возможно, больше, чем любые другие типы данных в Oracle. Они похожи на обычные файлы в файловой системе. Для того, чтобы писать в файл на filesytem, ​​вам придется

  1. открыть файл для записи
  2. усечь файл, если вы хотите, чтобы начать заполнение его с нуля
  3. читать ваши исходные данные в глыбы в цикле
  4. добавить свои куски данных в файл в том же цикле, один на один
  5. закрыть файл

более или менее то же самое верно и для LOBs. В вашей таблице столбец LOB (CLOB/BLOB/NCLOB) - это просто указатель/ссылка на другое место на вашем диске, на котором хранятся фактические данные. В стандартных выражениях Oracle указатель называется «Локатор больших объектов».Вы должны

  1. открыть/инициализировать локатор
  2. обрезает содержимое LOB, если вы хотите, чтобы начать заполнение его с нуля
  3. добавить свои куски данных на содержание больших объектов в цикле, по одному
  4. закрыть локатор

В PL/SQL это может выглядеть следующим образом:

-- create table blob_test(id number, b blob); 

declare 
    v_b blob; 
    aaa raw(32767); 
    longLine varchar2(32767); 
begin 
    longLine := LPAD('aaaa', 32767,'x'); 
    aaa := UTL_RAW.CAST_TO_RAW(longLine); 
    insert into blob_test values(1,empty_blob()) returning b into v_b; 
    dbms_lob.open(v_b,dbms_lob.lob_readwrite); 
    dbms_lob.writeappend(v_b,UTL_RAW.LENGTH (aaa) ,aaa); 
    dbms_lob.close(LOB_LOC=>v_b); 
    commit; 
end; 

Объяснение:

  1. инициализировать локатор = insert into blob_test values(1,empty_blob()) returning b into v_b;
  2. открыть локатор для записи = dbms_lob.open(v_b,dbms_lob.lob_readwrite);
  3. обрезает содержимое LOB, если вы хотите, чтобы начать заполнение его с нуля ... Это производится по вызову empty_blob() в insert.
  4. добавить свои куски данных к содержанию больших объектов в цикле, один за другим = здесь только одной итерации dbms_lob.writeappend(), добавляя только один кусок aaa длиной utl_raw.length(aaa) (максимум 32767) в больших объектах v_b
  5. закрыть LOB locator = dbms_lob.close(LOB_LOC=>v_b);
+0

Я не понимаю этого и не знаю, как я должен его использовать. Не могли бы вы объяснить, как я должен использовать этот скрипт в деталях, чтобы включить его? в моем собственном скрипте, который имеет несколько вложений, в случае, например, моя таблица называется «MYTABLE», и я хочу вставить строку или XML из 5000 символов, как бы она выглядела? – Weslor

+0

*) Информация о oracle direcroty и BFILENAME [Info ] (http://www.techonthenet.com/oracle/functions/bfilename.php) *) Загрузить файл [Пример] (http://www.anujparashar.com/blog/loading-text-file-into-clob -field-in-oracle) 1) Скопируйте свой xml в oracle_server. 2) Создайте каталог оракула. 3) Предоставьте права доступа к каталогу. 4) Следуйте примеру. –

+0

Вариант использования LOB-манипуляций слишком сильно зависит от фактического местонахождения самой манипуляции. Этот ответ хорошо дает общий пример, остальное должно быть на способности самообучения OP. – nop77svk

-1

Функция utl_raw.cast_to_raw преобразует значение типа данных VARCHAR2 в исходное значение. Очевидно, что длина строки ограничена типом данных VARCHAR2. Если вам нужно преобразовать большие текстовые данные в LOB, вы можете использовать процедуру DBMS_LOB.CONVERTTOBLOB.

Например, вы можете создать функцию для преобразования большого строкового значения (clob as input) в blob. что-то вроде этого:

create or replace function ClobToBlob (p_clob in clob) return blob is 
    l_dest_offset integer := 1; 
    l_source_offset integer := 1; 
    p_csid   number := 0; 
    l_lang_context integer := DBMS_LOB.DEFAULT_LANG_CTX; 
    l_warning  integer := DBMS_LOB.WARN_INCONVERTIBLE_CHAR; 
    l_tmpblob blob; 

    begin 
    dbms_lob.createtemporary(l_tmpblob, true); 
    DBMS_LOB.CONVERTTOBLOB 
    (
    l_tmpblob, 
    p_clob, 
    DBMS_LOB.LOBMAXSIZE, 
    l_dest_offset, 
    l_source_offset, 
    p_csid, 
    l_lang_context, 
    l_warning 
); 
    return l_tmpblob; 
end; 
Смежные вопросы