powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / ORA-01460 при загрузке BLOB-а размером более 32кб.
11 сообщений из 11, страница 1 из 1
ORA-01460 при загрузке BLOB-а размером более 32кб.
    #39833232
AndreyCreator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте.

Впервые наткнулся на очень странную проблему. Суть такова. Пишу программу под Linux на C++ с использованием Oracle Client. Пользуюсь функциями OCIStmtPrepare, OCIStmtExecute, OCIBindByPos и другими. При передаче BLOB-а в базу возникает ошибка, если его размер большое, чем 32кб. Выдается ошибка ORA-01460 "затребовано неразумное или нереализованное преобразование". BLOB-ы меньше 32кб грузятся нормально.

Что пробовал?
1. Под Windows через ODBC все грузится. Любые BLOB-ы любого размера. Сам писал прогу. Гружу по кускам через SQL_DATA_AT_EXEC, SQL_NEED_DATA и так далее. Все проходит без проблем.
2. Админ базы данных через свои средства любые BLOB-ы грузит без ограничений по размеру.
3. Я пробовал разбивать BLOB на куски. Биндить с параметром OCI_DATA_AT_EXEC и грузить через OCI_NEED_DATA / OCIStmtGetPieceInfo / OCIStmtSetPieceInfo. Все делал по документации с docs.oracle.com. Результат такой. Если суммарный размер кусков превышает 32кб, то возникает ошибка ORA-01460. Но, если таким способом грузить BLOB размером меньше 32кб, то все грузится.
4. Если биндить с параметром OCI_DYNAMIC_FETCH и использовать OCIStmtFetch, то сразу выдается OCI_ERROR c сообщением по поводу неправильно сформированного буфера для BLOB-а.
5. Пробовал устанавливать разные типы данных: SQLT_BIN, SQLT_CHR, SQLT_LBI, SQLT_LON и так далее. Все типы перебрал - результата никакого. Часть попыток оканчивается ошибкой несоответствия типов, а часть - той же ошибкой ORA-01460.
6. Бился головой об стенку.

Подскажите, как обойти ограничение на размер BLOB-а.
...
Рейтинг: 0 / 0
ORA-01460 при загрузке BLOB-а размером более 32кб.
    #39833240
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AndreyCreator6. Бился головой об стенку.

А надо - о документацию. SQLT_BIN и SQLT_CHR по определению ограничены 32к ибо это строки.
Надо использовать SQLT_BLOB/SQL_CLOB.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
ORA-01460 при загрузке BLOB-а размером более 32кб.
    #39833309
AndreyCreator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Уже пробовал ранее. Вот результаты:
Bind SQLT_BLOB через OCI_DATA_AT_EXEC и далее кусками по 32000 байт: ORA-24307: invalid length for piece.
Bind SQLT_BLOB через OCI_DATA_AT_EXEC и далее одним куском OCI_ONE_PIECE: ORA-24307: invalid length for piece.
Bind SQLT_BLOB через OCI_DEFAULT: Segmentation fault (core dumped).
SQLT_CLOB не подходит, так как данные бинарные (картинка).

Может быть, там допустимый размер куска как-то надо определять?
...
Рейтинг: 0 / 0
ORA-01460 при загрузке BLOB-а размером более 32кб.
    #39833317
AndreyCreator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ORA-24307: invalid length for piece.
Cause: The length of the piece exceeded the maximum possible size.
Action: Verify that the length of this piece and the cumulative length of all the previous pieces is not more than the desired value supplied by the application.

Все проверил. Распечатал размеры во время выполнения. Байт в байт совпадают. Оно гарантировано не "more than the desired value".
...
Рейтинг: 0 / 0
ORA-01460 при загрузке BLOB-а размером более 32кб.
    #39833329
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AndreyCreatorBind SQLT_BLOB через OCI_DEFAULT: Segmentation fault (core dumped).

Код показывай. У меня всё работает:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
ora_Call(ora_LobCreateTemporary(Svc, Err, var->lob,
                           OCI_DEFAULT, SQLCS_IMPLICIT, lob_type,
                           FALSE, OCI_DURATION_SESSION), Err, "TOS::SetAsString-LCT");
ub4 Amount = length;
ora_Call(ora_LobWrite(Svc, Err, var->lob, &Amount, 1,
                      (void*)buffer, length,
                      OCI_ONE_PIECE, NULL, NULL, 0, SQLCS_IMPLICIT),
                              Err, "TOS::SetAsString-LW");


Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
ORA-01460 при загрузке BLOB-а размером более 32кб.
    #39833397
AndreyCreator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov,

Я не через LobCreate/LobWrite делал, а просто указатель на массив байт передавал. Наверное, проблема в этом.

Подскажите, в какой последовательности функции вызываются?

OCIDescriptorAlloc(... (out)locator, OCI_DTYPE_LOB, my_massive_size, ... );
OCILobCreateTemporary(... (in)locator , OCI_DEFAULT, OCI_DEFAULT, OCI_TEMP_BLOB, false, OCI_DURATION_CALL);
OCILobWrite(... (in)locator, 1, my_massive_ptr, my_massive_size, OCI_ONE_PIECE, NULL, NULL, 0, SQLCS_IMPLICIT),
OCIStmtPrepare(...);
OCIBindByPos(... (in)locator, LobSize, ... SQLT_BLOB ... OCI_DEFAULT);
OCIStmtExecute(...);
OCILobClose(... (in)locator);

Правильно?
...
Рейтинг: 0 / 0
ORA-01460 при загрузке BLOB-а размером более 32кб.
    #39833467
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AndreyCreatorПравильно?

LobClose не вызывается. Вместо него надо освобождать дескриптор.
Ну и StmtPrepare я бы вызывал первым, но это дело вкуса.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
ORA-01460 при загрузке BLOB-а размером более 32кб.
    #39833764
AndreyCreator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
OCILobLocator *locator;
unsigned int blobsize = reinterpret_cast<QByteArray *>(data)->size();
ub4 amtp = blobsize;
r = OCIDescriptorAlloc(env, (void **)&locator, OCI_DTYPE_LOB, 0, 0);
if (r!=OCI_SUCCESS && r!=OCI_SUCCESS_WITH_INFO) { printf("OCIDescriptorAlloc failed\n"); return r; }
r = OCILobCreateTemporary(svc, err, locator, OCI_DEFAULT, OCI_DEFAULT, OCI_TEMP_BLOB, false, OCI_DURATION_SESSION);
if (r!=OCI_SUCCESS && r!=OCI_SUCCESS_WITH_INFO) { printf("OCILobCreateTemporary failed\n"); return r; }
r = OCILobWrite(svc, err, locator, &amtp, 1, reinterpret_cast<QByteArray *>(data)->data(), blobsize, OCI_ONE_PIECE, NULL, NULL, 0, SQLCS_IMPLICIT);
if (r!=OCI_SUCCESS && r!=OCI_SUCCESS_WITH_INFO) { printf("OCILobWrite failed\n"); return r; }
r = OCIBindByPos(sql, hbnd, err, pos + 1, locator, blobsize, SQLT_BLOB, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
if (r!=OCI_SUCCESS && r!=OCI_SUCCESS_WITH_INFO) { printf("OCIBindByPos failed\n"); return r; }

OCIBindByPos вызывает Segmentation fault core dumped. До OCIStmtExecute не доходит. Тестировал функции отдельно путем закоментаривания того, что идет ниже. Если блоб не грузить, то все нормально. OCIDescriptorAlloc, OCILobCreateTemporary, OCILobWrite ошибок не вызывают. Как только включаю OCIBindByPos - сразу идет Segmentation fault core dumped и только с параметром SQLT_BLOB (с SQLT_BIN такой ошибки нет).
...
Рейтинг: 0 / 0
ORA-01460 при загрузке BLOB-а размером более 32кб.
    #39833784
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AndreyCreatorOCIBindByPos вызывает Segmentation fault core dumped.

Потому что ей надо скармливать не сам локатор, а его адрес.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
ORA-01460 при загрузке BLOB-а размером более 32кб.
    #39833787
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И размер - 0, а не blobsize.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
ORA-01460 при загрузке BLOB-а размером более 32кб.
    #39833789
AndreyCreator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov,

Спасибо, все заработало.
...
Рейтинг: 0 / 0
11 сообщений из 11, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / ORA-01460 при загрузке BLOB-а размером более 32кб.
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]