Конвертировать BLOB в BLOB
Я использую оракул 11g, и я пытаюсь выяснить длину текста. Я обычно буду использовать select length (myvar) из таблицы, но я не могу этого сделать.
Таблица, которую я хочу запросить, имеет столбец BLOB, в котором сохраняются символы или фотографии. Я хочу знать количество символов, в которых есть мой столбец BLOB.
Я пытался преобразовать свой BLOB в символ, используя UTL_RAW.CAST_TO_VARCHAR2(myblob) из таблицы, но эта функция работает неправильно или, возможно, я делаю ошибку.
Например: мой BLOB имеет слово Section, когда я вижу это в базе данных в шестнадцатеричной форме, я вижу Section. Я не знаю, почему в каждой букве есть эти точки. Тогда я использовал этот запрос
select UTL_RAW.CAST_TO_VARCHAR2(myblob)
from table
Результатом этого запроса является 'S', поэтому это не полное слово, которое имеет мой BLOB, и когда я делаю этот запрос
select length(UTL_RAW.CAST_TO_VARCHAR2(myblob))
from table
результат - 18, а слово Sections не имеет 18 символов.
Я пытался преобразовать BLOB-объект в varchar, хотя я думаю, что мой лучший выбор - это clob, потому что длина текста, который он может сохранить, превышает предел, который имеет varchar. Я попытался сделать это, сделав этот запрос (я не уверен, что это правильно, но это то, что я нашел в интернете)
select UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(myblob, 32767, 1))
from table
Этот запрос также возвращает 'S'
Я надеюсь, что вы можете помочь мне с этой проблемой. спасибо за продвинутый
3 ответа
Для всех, кто заходит в эту ветку и хочет знать, как конвертировать BLOB-объект в Clob. Вот пример.
create function clobfromblob(p_blob blob) return clob is
l_clob clob;
l_dest_offsset integer := 1;
l_src_offsset integer := 1;
l_lang_context integer := dbms_lob.default_lang_ctx;
l_warning integer;
begin
if p_blob is null then
return null;
end if;
dbms_lob.createTemporary(lob_loc => l_clob
,cache => false);
dbms_lob.converttoclob(dest_lob => l_clob
,src_blob => p_blob
,amount => dbms_lob.lobmaxsize
,dest_offset => l_dest_offsset
,src_offset => l_src_offsset
,blob_csid => dbms_lob.default_csid
,lang_context => l_lang_context
,warning => l_warning);
return l_clob;
end;
Чтобы конвертировать BLOB в BLOB, попробуйте это:
SELECT TO_CLOB(UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(MYBLOB,2000)))
FROM MYTABLE;
SELECT DBMS_LOB.GetLength( myblob ) length_in_bytes
FROM table
вернет длину BLOB в байтах. Похоже, что символьные данные в вашем BLOB, вероятно, кодируются с использованием набора символов UTF-16, поэтому число байтов, вероятно, вдвое больше количества символов (в зависимости от используемой версии Unicode и конкретных сохраняемых данных, некоторые символам может потребоваться 4 байта памяти, но маловероятно, что вы имеете дело с любым из этих символов).
Вы можете использовать DBMS_LOB.ConvertToClob
процедура для преобразования BLOB в CLOB (хотя, поскольку это процедура, вам необходимо вызывать ее в блоке PL/SQL). В рамках этого преобразования вам почти наверняка потребуется указать набор символов, в который закодированы данные - я предполагаю, что ваше приложение использует набор символов UTF-16, но это всего лишь предположение.
Только преобразование в CLOB:
select TO_CLOB(UTL_RAW.CAST_TO_VARCHAR2(YOURCLOB)) from DUAL;
Вдохновлен Крейгом без ограничений по размеру.