coracle-databaseoracle-call-interfaceodpi-c

How to fetch oracle type NUMBER as string or int/uint?


I'm fetching a row from oracle database using ODPI-C in C++ and NUMBER(19,0) type appears to be double, so in some cases the field value comes corrupted (e.g. in db viewer shows 5187413295700304461 but after fetch it's transformed into 5.1874132957002998e+18 which is not quite correct).

Reading the field value is done by

int dpiStmt_getQueryValue(dpiStmt *stmt, uint32_t pos, dpiNativeTypeNum *nativeTypeNum, dpiData **data);

which return parameter dpiNativeTypeNum nativeTypeNum is set to DPI_ORACLE_TYPE_NUMBER

The return parameter dpiQueryInfo info of

int dpiStmt_getQueryInfo(dpiStmt *stmt, uint32_t pos, dpiQueryInfo *info);

function indicates that field should be read asDouble.

UPDATE

I'm not sure but in OCI (of which wrapper is ODPI-C) there is a function called OCINumberToText. I suppose that this kind of function is what I need.

Also there is a class ResultSet which has member function called getString(unsigned int colIndex) which does exactly what I need (converts NUMBER(19,0) to std::string).

UPDATE 2

I found a member field called dpiDataTypeInfo.ociTypeCode with a comment "Specifies the OCI type code for the data, which can be useful if the type is not supported by ODPI-C" from here https://oracle.github.io/odpi/doc/structs/dpiDataTypeInfo.html#dpidatatypeinfo

but how to use this for calling OCI functions ?


Solution

  • Rows can be fetch using dpiVar*s. Simply before dpiStmt_fetch I defined dpi_Var* using this call

    dpiStmt_defineValue(statement, 1, DPI_ORACLE_TYPE_NUMBER, DPI_NATIVE_TYPE_BYTES, 0, 0, nullptr)
    

    You can notice that in that call oracle type is set to DPI_ORACLE_TYPE_NUMBER but native type is set to DPI_NATIVE_TYPE_BYTES.

    After fetch the data is acquired using dpiStmt_getQueryValue, and read asBytes.