【问题标题】:CRecordset::GetFieldValue() with BIGINTCRecordset::GetFieldValue() 与 BIGINT
【发布时间】:2019-08-23 17:10:21
【问题描述】:

谁能帮我弄清楚如何从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 语句中的字段类型之一。

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

【问题讨论】:

    标签: c++ odbc crecordset


    【解决方案1】:

    好吧,我找不到 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 的代码,我认为这种方法要快一些,所以我为所有支持的数据类型实现了它,并且看起来效果很好。

    【讨论】:

      猜你喜欢
      • 2017-04-26
      • 2018-10-31
      • 2011-10-05
      • 2018-11-06
      • 2010-10-31
      • 1970-01-01
      • 2018-05-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多