CRecordset::GetFieldValue() 与 BIGINT

CRecordset::GetFieldValue() with BIGINT

谁能帮我弄清楚如何从 CRecordset 中读取 __int64 值?

我的代码看起来像这样:

CDBVariant var;
CRecordset rs(&db);

rs.Open(CRecordset::forwardOnly, L"SELECT col FROM Customers");
rs.GetFieldValue((short)0, m_Var, SQL_C_SBIGINT);

但是对 GetFieldValue() 的调用产生了错误:

Invalid argument value

跟踪代码,我看到 CRecordset::GetDataBuffer() 断言,因为 SQL_C_SBIGINT(或 SQL_C_BIGINT 就此而言)不是 switch 语句中的字段类型之一。

在这上面花了一个多小时之后,我发现很多文档表明这应该是可能的,尽管没有一个例子。有谁知道能不能做到?

嗯,我找不到 CRecordset 的好方法。

由于 CRecordset 是 Windows ODBC 函数的包装器,我发现我可以通过深入到较低级别的函数来实现它。下面的方法是 class 派生自 CRecordset.

的一部分
__int64 CRecordsetEx::GetInt64FieldValue(int nField)
{
    __int64 val = 0;
    GetData(nField, SQL_C_SBIGINT, &val, sizeof(val));
    return val;
}

long CRecordsetEx::GetData(int nField, short type, LPVOID pBuffer, int nBufferSize)
{
    SQLINTEGER nActualLength;
    SQLRETURN r = ::SQLGetData(m_hstmt, (short)nField + 1, type, pBuffer, nBufferSize, &nActualLength);

    if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO)
    {
        ASSERT(FALSE);

        TCHAR szBuffer[10];
        TCHAR szMessage[100];
        SQLINTEGER nError;

        if (::SQLGetDiagRec(SQL_HANDLE_STMT, m_hstmt, 1, szBuffer, &nError, szMessage, 100, NULL) == SQL_SUCCESS)
            ::AfxThrowDBException(r, m_pDatabase, m_hstmt);
    }

    // Note: nActualLength set to SQL_NULL_DATA if field was NULL
    return nActualLength;
}

事实上,查看 CRecordset 的代码,我认为这种方法更快一些,所以我为所有支持的数据类型实现了它,它似乎运行良好。