Retrieving data type information for columns in an Oracle OCCI ResultSet
After sending a simple query via OCCI (example: select * from ALL_USERS) I'm in the need to know the datatype for the column, for the moment I've been playing with the ResultSet::getColumnListMetaData() method without success.
Questions:开发者_运维技巧 1. How can I get the datatype by using the aforementioned method and the MetaData class? 2. Is there any better documentation out there than the one already provided by oracle?I've got this old code laying around, I guess it does exactly what you want. Its using OCI, not OCCI, but maybe it helps.
/* 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 );
EDIT: As per ypour request:
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;
}
}
You can use method:
MetaData::getInt(occi::MetaData::ATTR_DATA_TYPE);
and compare returned value with constants from enumeration of possible types which you can find in occiCommon.h:
enum Type { OCCI_SQLT_CHR=SQLT_CHR, OCCI_SQLT_NUM=SQLT_NUM ... }
Can't add a comment due to low reputation. In case someone is interested in an OCCI example based on the answer by Pustovalov Dmitry.
auto results = statement->executeQuery(selectCommand);
auto columnMetaData = results->getColumnListMetaData();
while (results->next())
{
for ( size_t index = 0; index < columnMetaData.size(); ++index )
{
// Column Meta data is std::vector - zero based indexing while
// Oracle result-set getxyz() methods have one based indexing.
cout << "Column name: " << columnMetaData[index].getString(MetaData::ATTR_NAME) << endl;
switch(columnMetaData[index].getInt(MetaData::ATTR_DATA_TYPE))
{
case OCCI_SQLT_CHR:
cout << results->getString(index+1) << endl;
break;
case OCCI_SQLT_TIMESTAMP:
cout << results->getTimestamp(index+1).toText("YYYYMMDD HH24:MI:SS.FF", 0) << endl;
break;
}
}
}
More details available here
精彩评论