Пишу на OCCI/OCI.
Хочу передать CLOB в PL/SQL процедуру:
PROCEDURE set_clob
(
pnID IN NUMBER,
pClob IN CLOB
)
IS
BEGIN
NULL;
END set_clob;
Как сделать временный клоб на OCCI не нашел, поэтому пытаюсь сделать так на OCI:
(все функции OCI возвращают OCI_SUCCESS, ошибка происходит на этапе execute())
void TestClob2(Environment* pEnvironment, Connection* pConn)
{
Statement* stmt = pConn->createStatement( "begin ot_customer.set_clob(45904503, :p0); end;" );
OCIEnv* pEnv = pEnvironment->getOCIEnvironment();
OCISvcCtx* svchp = pConn->getOCIServiceContext();
std::vector< char > clobBuffer(10, 'A');
// создаем handle для ошибок
OCIError* ociError = 0;
sword s = OCIHandleAlloc(pEnv, (void**)&ociError, OCI_HTYPE_ERROR, 0, 0);
// создаем локатор
OCILobLocator* locator = 0;
s = OCIDescriptorAlloc(pEnv, (void **)&locator, OCI_DTYPE_LOB, 0, 0);
// создаем временный клоб
s = OCILobCreateTemporary(svchp, ociError, locator, OCI_DEFAULT, SQLCS_IMPLICIT, OCI_TEMP_CLOB, FALSE, OCI_DURATION_SESSION);
// записываем данные в клоб
ub4 amtp = ub4( clobBuffer.size() );
ub4 buflen = amtp;
s = OCILobWrite(svchp, ociError, locator, &amtp, 1, &clobBuffer[0], buflen, OCI_ONE_PIECE, 0, 0, 0, 0 );
// связываем параметр типа клоб
sb2 indicator = 0;
OCIBind* bndp = 0;
s = OCIBindByPos(stmt->getOCIStatement(), &bndp, ociError, 1, (dvoid *)&locator, -1, SQLT_CLOB, (dvoid *)indicator, 0, 0, 0, 0, OCI_DEFAULT);
try
{
stmt->execute(); // выкидывает исключение ORA-24813: cannot send or receive an unsupported LOB
}
catch(SQLException& e)
{
std::cout << "SQLException: " << e.getMessage() << std::endl;
std::cout << "error code=" << e.getErrorCode() << std::endl;
}
OCILobFreeTemporary(svchp, ociError, locator);
OCIDescriptorFree(locator, OCI_DTYPE_LOB);
pConn->terminateStatement( stmt );
}
Подскажите, пожалуйста, как правильно передать CLOB параметр в PL/SQL процедуру.
Здравствуйте, Wasilij, Вы писали:
W>Пишу на OCCI/OCI.
W>Хочу передать CLOB в PL/SQL процедуру:
W>Как сделать временный клоб на OCCI не нашел....
Нашел как сделать временный клоб на OCCI:
bool CreateTempClob(Connection* pConn, Clob& c)
{
bool result = false;
Statement* stmt = 0;
try
{
stmt = pConn->createStatement("begin dbms_lob.createtemporary(:p1, FALSE);end;");
stmt->registerOutParam(1, OCCICLOB);
stmt->executeUpdate();
c = stmt->getClob(1);
result = true;
}
catch(SQLException &e)
{
std::stringstream ss;
ss << "CreateTempClob FAILED 1: errorCode=" << e.getErrorCode() << ", errorText=" << e.getMessage();
std::cout << ss.str() << std::endl;
}
try
{
if(stmt != 0)
{
pConn->terminateStatement(stmt);
}
}
catch(SQLException &e)
{
result = false;
std::stringstream ss;
ss << "CreateTempClob FAILED 2: errorCode=" << e.getErrorCode() << ", errorText=" << e.getMessage();
std::cout << ss.str() << std::endl;
}
return result;
}