Мы читаем данные из CLOB в std::vector
через OCCI. Упрощенный код выглядит следующим образом:
oracle::occi::Clob clob = result.getClob( 3 );
unsigned len = clob.length();
std::vector< unsigned char > result( len );
unsigned have_read = clob.read( len , result.data() , len );
Это приводит к ошибке ORA-32116, говорящей о том, что размер буфера (3-й аргумент чтения) должен быть равен или превышать объем данных, которые должны быть прочитаны (1-й аргумент чтения). Это условие, по-видимому, выполняется.
После увеличения размера буфера до 4 * len:
unsigned have_read = clob.read(len , result.data() , 4 * len);
операция выполнена правильно. Пока что значения have_read
а также len
были всегда одинаковыми.
Есть ли недокументированное дополнительное пространство, необходимое для буфера? Или нужны полные страницы?
Мы используем «Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 — 64bit».
Любые разъяснения по теме приветствуются.
Я подозреваю, что в вашем CLOB есть многобайтовые символы.
Согласно документации clob.length()
«возвращает количество символов в CLOB
« тогда как buffsize
параметр clob.read()
говорится, что «действительными значениями являются числа, большие или равные amt
«, который в свою очередь говорит, что это «количество байтов для чтения».
Другими словами (и согласно документации) вы передаете количество символов clob.read()
когда он ожидает количество байтов. Тот факт, что вы получаете сообщение об ошибке, предполагает, что первое меньше второго.
Документация предлагает изменить буфер на utext
, после установки набора символов с помощью setCharSetId()
бы исправить это.
В качестве альтернативы, если у вас есть многобайтовые символы и вам не нужно делать какие-либо символьные представления (не знаю), возможно, стоит вместо этого работать с BLOB; blob.length()
возвращает количество байтов.