Функция RawToHex в Oracle 11g возвращает шестнадцатеричное представление любого необработанного значения.
Эта функция возвращает значение Hex как varchar2.
Что произойдет, если я передам BLOB в функцию RawToHex (), которая приведет к шестнадцатеричному представлению, превышающему ограничение varchar2, равное 4000?
Есть ли способ конвертировать очень большие BLOB-объекты в шестнадцатеричное представление?
ОБНОВЛЕНИЕ:
Я провел небольшое расследование и нашел ответ на первую часть моего вопроса.
Я могу передать BLOB в функцию RawToHex, и она будет успешно выполняться до тех пор, пока вы не достигнете границ Raw DataType. Похоже, что Oracle неявно конвертирует из BLOB в Raw.
DECLARE
a varchar2(32767);
b blob;
BEGIN
select blob_column into b from a_table where a_table_id = 1;
dbms_output.put_line(dbms_lob.getlength(b)); --> output: 216
dbms_output.put_line(rawtohex(empty_blob())); --> converted blob
select blob_column into b from a_table where a_table_id = 2;
dbms_output.put_line(dbms_lob.getlength(b)); --> output: 140000
dbms_output.put_line(rawtohex(empty_blob())); --> ORA-06502: PL/SQL: numeric or value error
END;
Описание этой ошибки согласно ora-code.com
ORA-06502: PL / SQL: строка ошибки числового значения или значения
Причина: произошла ошибка арифметического, числового, строкового преобразования или преобразования. Например, эта ошибка возникает, если предпринята попытка присвоить значение NULL переменной, объявленной NOT NULL, или если предпринята попытка присвоить целое число больше 99 переменной, объявленной NUMBER (2).
Действие: измените данные, то, как они обрабатываются или как они объявляются, чтобы значения не нарушали ограничения.
ОБНОВЛЕНИЕ 2:
У меня есть решение этой проблемы. Разбиение сгустка на более мелкие блоки и их постепенное преобразование. Это дает правильный результат. Это правильный подход или это решение может в какой-то момент упасть?
function BlobToHex(data in blob) return clob
is
v_clob clob;
v_start pls_integer := 1;
v_buffer pls_integer := 4000;
begin
if data is null
then
return '""';
end if;
dbms_lob.createtemporary(v_clob, true);
dbms_lob.append(v_clob, '0x');
for i in 1..ceil(dbms_lob.getlength(data) / v_buffer)
loop
dbms_lob.append(v_clob, rawtohex(DBMS_LOB.SUBSTR(data, v_buffer, v_start)));
v_start := v_start + v_buffer;
end loop;
return v_clob;
end;