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
的代码,我认为这种方法更快一些,所以我为所有支持的数据类型实现了它,它似乎运行良好。
谁能帮我弄清楚如何从 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
的代码,我认为这种方法更快一些,所以我为所有支持的数据类型实现了它,它似乎运行良好。