CRecordset::GetFieldValue() with BIGINT

CRecordset::GetFieldValue() with BIGINT

本文关键字:with BIGINT GetFieldValue CRecordset      更新时间:2023-10-16

谁能帮我弄清楚如何从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()会产生错误:

参数值无效

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

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

好吧,我找不到CRecordset的好方法.

由于CRecordset是 Windows ODBC 函数的包装器,我发现我能够通过向下访问较低级别的函数来使其工作。下面的方法是派生自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的代码,我认为这种方法更快一些,因此我为所有支持的数据类型实现了此方法,并且似乎运行良好。