C++ CRecordset::快照不';我不再在VS2012中工作了-什么';还有什么选择?

C++ CRecordset::快照不';我不再在VS2012中工作了-什么';还有什么选择?,c++,winapi,mfc,odbc,C++,Winapi,Mfc,Odbc,显然,在VS2012中,SQL\u CUR\u USE\u ODBC已被弃用。[更新:游标库似乎已从VS2012中完全删除] MFC的CDATA库不再使用它(而它是VS2010和MFC早期版本的默认值),而是使用SQL\u CUR\u use\u驱动程序 不幸的是,SQL\u CUR\u USE\u驱动程序不能与Jet ODBC驱动程序一起正常工作(我们正在与Access数据库交互)。驱动程序最初声称支持位置操作(但不支持位置更新),但当尝试实际查询数据库时,所有并发模型都会失败,直到MFC库下

显然,在VS2012中,SQL\u CUR\u USE\u ODBC已被弃用。[更新:游标库似乎已从VS2012中完全删除]

MFC的CDATA库不再使用它(而它是VS2010和MFC早期版本的默认值),而是使用SQL\u CUR\u use\u驱动程序

不幸的是,SQL\u CUR\u USE\u驱动程序不能与Jet ODBC驱动程序一起正常工作(我们正在与Access数据库交互)。驱动程序最初声称支持位置操作(但不支持位置更新),但当尝试实际查询数据库时,所有并发模型都会失败,直到MFC库下降到与数据库的只读交互(这对我们来说是不可能的)

问题

  • 这是微软最新的一次尝试,迫使开发人员从基于Jet的数据源迁移到SQL Express(或类似产品)吗
  • 通过VS 2012版本的MFC/ODBC,我们是否应该使用另一种方式与Access数据库交互?(1)
另见:


更新:查看各种选项,光标库似乎已从VS2012的ODBC库中删除。再加上Jet不能正确支持位置更新(2),这使得“快照”模式无法使用。只要底层表有主键,它似乎就支持“dynaset”。无眼表与“动态集”模式(3)不兼容。所以-我可以坚持使用VS 2010,或者我可以更改我的表以包含自动编号或类似的内容,以确保pkey可用,这样我就可以对记录集使用动态集模式


(1) 例如,我们应该为CRecordset使用不同的开放式吗?我们目前使用CRecordset::snapshot。但我从来没有真正理解过快照、动态和动态集的各种模式。一组快速的“每个尝试”都无法为access数据库获取可更新的工作界面…
(2) 它在最初查询时声明为,但随后返回它以前声明支持的所有并发模式的错误
(3) “dynamic”也不适用,因为Jet根本不支持它(从我的测试中可以看出)。

派生和重写。在派生类
CMyDatabase
中,将对
AllocConnect
的调用替换为对
MyAllocConnect
的调用。显然,您的
MyAllocConnect
函数应该使用所需参数调用:

// Turn on cursor lib support
if (dwOptions & useCursorLib)
{
    AFX_SQL_SYNC(::SQLSetConnectOption(m_hdbc, SQL_ODBC_CURSORS, SQL_CUR_USE_ODBC));
    // With cursor library added records immediately in result set
    m_bIncRecordCountOnAdd = TRUE;
}

然后使用您的
CMyDatabase
类而不是
CDatabase
进行所有查询。

如果其他人遇到此问题,下面是答案:

对于Access数据库的ODBC,请使用CDATA基本mydb连接;mydb.OpenEx(..,0),以便要求系统不要加载游标库

然后对于记录集,使用dynaset CMyRecordset myrs;myrs.Open(CRecordset::dynaset,…)


最后,为了使用动态集(键集),您必须确保您的表具有主键。

我找到了一个似乎可行的解决方案。我以与VS 2012完全相同的方式重写OpenEx,因为我们需要它来调用AllocConnect的子版本,因为它在父版本中不是虚拟的。如前所述,我还覆盖了AllocConnect。在CDATA的派生版本中,请尝试以下代码:

MyCDatabase.h

BOOL OpenEx(LPCTSTR lpszConnectString, DWORD dwOptions = 0);
void AllocConnect(DWORD dwOptions);
MyCDatabase.cpp

BOOL MyCDatabase::OpenEx(LPCTSTR lpszConnectString, DWORD dwOptions)
{
ENSURE_VALID(this);
ENSURE_ARG(lpszConnectString == NULL || AfxIsValidString(lpszConnectString));
ENSURE_ARG(!(dwOptions & noOdbcDialog && dwOptions & forceOdbcDialog));

// Exclusive access not supported.
ASSERT(!(dwOptions & openExclusive));

m_bUpdatable = !(dwOptions & openReadOnly);

TRY
{
    m_strConnect = lpszConnectString;

    DATA_BLOB connectBlob;
    connectBlob.pbData = (BYTE *)(LPCTSTR)m_strConnect;
    connectBlob.cbData = (DWORD)(AtlStrLen(m_strConnect) + 1) * sizeof(TCHAR);
    if (CryptProtectData(&connectBlob, NULL, NULL, NULL, NULL, 0, &m_blobConnect))
    {
        SecureZeroMemory((BYTE *)(LPCTSTR)m_strConnect, m_strConnect.GetLength() * sizeof(TCHAR));
        m_strConnect.Empty();
    }

    // Allocate the HDBC and make connection
    AllocConnect(dwOptions);
    if(!CDatabase::Connect(dwOptions))
        return FALSE;

    // Verify support for required functionality and cache info
    VerifyConnect();
    GetConnectInfo();
}
CATCH_ALL(e)
{
    Free();
    THROW_LAST();
}
END_CATCH_ALL

return TRUE;
}

void MyCDatabase::AllocConnect(DWORD dwOptions)
{
CDatabase::AllocConnect(dwOptions);

dwOptions = dwOptions | CDatabase::useCursorLib;

// Turn on cursor lib support
if (dwOptions & useCursorLib)
{
    ::SQLSetConnectAttr(m_hdbc, SQL_ATTR_ODBC_CURSORS, (SQLPOINTER)SQL_CUR_USE_ODBC, 0);
    // With cursor library added records immediately in result set
    m_bIncRecordCountOnAdd = TRUE;
}
}
请注意,您不想首先将useCursorLab传递给OpenEx,您需要在AllocConnect的黑客版本中覆盖它


还要注意的是,这只是一个黑客,但它似乎工作。请测试您的所有代码,以确保其按预期工作,但到目前为止,它对我来说工作正常。

尝试了-失败“无法加载光标库”。MS似乎实际删除了光标库。恢复它可能是可能的(从VS 2010中拉出来-链接到旧的ODBC),但是随着VS 2012的提供,它是一个不可能的。MS给出了关于ODBC和Jet的非常复杂的消息。DAO已被弃用,但Jet仍然是他们用于访问的ODBC驱动程序引擎,我没有发现任何具体的迹象表明他们已弃用作为产品的访问,或者他们正在从ODBC中删除对访问的支持。他们表示ODBC将在XP前后退役,但后来又反悔了,新的管理者表示ODBC将继续成为他们数据库连接技术中的一个重要支柱。所以根据您所阅读的内容,有时它似乎正在消亡,而另一些时候它似乎正在衰退中。在将一些遗留ODBC SQL代码从VS2010升级到VS2015之后,您今天感觉到了痛苦。微软对此错误的回应是:;他们告诉我们“在SQL论坛上提问”。这是一位真正的MS库开发人员提供的。好像我们需要更多的理由从MFC迁移出去。我真的认为这是MFC中的一个bug。ODBC_游标枚举不应与SQL_CUR_USE_驱动程序枚举一起使用。上面的代码有效地解决了这个问题,但如果Microsoft能够解决这个问题,那就太好了,即使它是针对遗留库的。有很多旧程序出于各种原因需要这个库。很有趣。。。。所以你没有得到一个游标库加载失败的错误?这是针对ACCESS或SQL Server的?我们将其用于可以连接到SQL Server或Oracle的ODBC连接。它似乎工作完美无瑕。到目前为止,我们运气不错。几天前,我们刚刚迁移到2012年,到目前为止,这一切都很有效。我希望它能帮助你!