检索Oracle OCCI ResultSet中列的数据类型信息

时间:2010-07-26 19:04:54

标签: c++ oracle

通过OCCI发送简单查询后(例如:select * from ALL_USERS)我需要知道列的数据类型,目前我一直在玩 ResultSet :: getColumnListMetaData( )方法没有成功。
问题:
 1.如何使用上述方法和MetaData类获取数据类型?
 2.有没有比oracle已经提供的更好的文档?

3 个答案:

答案 0 :(得分:2)

我已经有了这个旧代码,我猜它确实是你想要的。它使用的是OCI,而不是OCCI,但也许有帮助。

/* 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 );

编辑:根据ypour请求:

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;
}
}

答案 1 :(得分:0)

您可以使用方法:

MetaData::getInt(occi::MetaData::ATTR_DATA_TYPE);

并将返回值与可以在occiCommon.h中找到的可能类型的枚举中的常量进行比较:

enum Type { OCCI_SQLT_CHR=SQLT_CHR, OCCI_SQLT_NUM=SQLT_NUM  ... }

答案 2 :(得分:0)

由于信誉低而无法添加评论。 如果有人对基于Pustovalov Dmitry的答案的OCCI示例感兴趣。

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;
        }
    }
}

更多详细信息可用here