Eu tenho esse código antigo por aí, acho que faz exatamente o que você quer. Está usando OCI, não OCCI, mas talvez ajude.
/* Get the number of columns in the query */
ub4 colCount = 0;
oraCheckErr( m_err, OCIAttrGet((dvoid *)_stmt, OCI_HTYPE_STMT, (dvoid *)&colCount,
0, OCI_ATTR_PARAM_COUNT, m_err));
ub2 oraType = 0;
OCIParam *col = 0;
ub4 nameLen, colWidth, charSemantics;
text *name;
for (ub4 i = 1; i <= colCount; i++)
{
/* get parameter for column i */
oraCheckErr( m_err, OCIParamGet((dvoid *)_stmt, OCI_HTYPE_STMT, m_err, (dvoid**)&col, i));
/* get data-type of column i */
oraType = 0;
oraCheckErr( m_err, OCIAttrGet((dvoid *)col, OCI_DTYPE_PARAM,
(dvoid *)&oraType, 0, OCI_ATTR_DATA_TYPE, m_err));
/* Retrieve the column name attribute */
nameLen = 0;
oraCheckErr( m_err, OCIAttrGet((dvoid*)col, OCI_DTYPE_PARAM,
(dvoid**) &name, &nameLen, OCI_ATTR_NAME, m_err ));
/* Retrieve the length semantics for the column */
charSemantics = 0;
oraCheckErr( m_err, OCIAttrGet((dvoid*)col, OCI_DTYPE_PARAM,
(dvoid*) &charSemantics,0, OCI_ATTR_CHAR_USED, m_err ));
colWidth = 0;
if (charSemantics)
/* Retrieve the column width in characters */
oraCheckErr( m_err, OCIAttrGet((dvoid*)col, OCI_DTYPE_PARAM,
(dvoid*) &colWidth, 0, OCI_ATTR_CHAR_SIZE, m_err ));
else
/* Retrieve the column width in bytes */
oraCheckErr( m_err, OCIAttrGet((dvoid*)col, OCI_DTYPE_PARAM,
(dvoid*) &colWidth,0, OCI_ATTR_DATA_SIZE, m_err ));
_elements.output.push_back( SQLElement( String(reinterpret_cast<char*>(name), nameLen), getSQLTypes( oraType ), i, colWidth ));
}
OCIHandleFree ( (dvoid*) _stmt, OCI_HTYPE_STMT );
EDITAR: Conforme seu pedido:
SQLTypes getSQLTypes(ub2 _oracleType)
{
switch( _oracleType )
{
case SQLT_INT:
return stInt;
case SQLT_FLT:
case SQLT_BDOUBLE:
return stDouble;
case SQLT_BFLOAT:
return stFloat;
case SQLT_ODT:
return stDate;
case SQLT_DATE:
case SQLT_TIMESTAMP:
case SQLT_TIMESTAMP_TZ:
case SQLT_TIMESTAMP_LTZ:
return stTimeStamp;
case SQLT_CHR:
case SQLT_NUM:
case SQLT_STR:
case SQLT_VCS:
default:
return stText;
}
}