我们有一个通过 MFC (VS2010) 中的 CDatabase/CRecordset 使用 ODBC 的应用程序。我们实现了两个后端。MSSQL 和 MySQL。
现在,当我们使用 MSSQL(使用 Native Client 10.0)时,通过慢速链接(例如 VPN)使用 SELECT 检索记录非常慢。MySQL ODBC 驱动程序不会表现出这种讨厌的行为。
例如:
CRecordset r(&m_db);
r.Open(CRecordset::snapshot, L"SELECT a.something, b.sthelse FROM TableA AS a LEFT JOIN TableB AS b ON a.ID=b.Ref");
r.MoveFirst();
while(!r.IsEOF())
{
// Retrieve
CString strData;
crs.GetFieldValue(L"a.something", strData);
crs.MoveNext();
}
现在,有了 MySQL 驱动程序,一切都可以正常运行了。查询返回,一切都快如闪电。但是,对于 MSSQL Native Client,事情会变慢,因为在每个 MoveNext() 上,驱动程序都会与服务器通信。
我认为这是由于服务器端游标,但我没有找到禁用它们的方法。我试过使用:
::SQLSetConnectAttr(m_db.m_hdbc, SQL_ATTR_ODBC_CURSORS, SQL_CUR_USE_ODBC, SQL_IS_INTEGER);
但这也无济于事。SQL Profiler 中仍然有 sp_cursorfetch() 等的长期运行的 exec。我还尝试了一个带有 SQLAPI 和批量提取的小型参考项目,但它也在 FetchNext() 中挂起很长时间(即使结果集中只有一条记录)。然而,这只发生在使用 LEFT JOINS、表值函数等 的查询上。请注意,查询不会花费那么长时间- 通过 SQL Studio 在相同的连接上执行相同的 SQL 会在合理的时间内返回。
问题1:是否有可能以某种方式让本机客户端访问在本地“缓存”所有结果以与 MySQL 驱动程序类似的方式使用本地游标?
也许这完全是错误的方法,但我不知道该怎么做。
我们想要的只是一次从 SELECT 中检索所有数据,然后在下一次查询之前不再与服务器通信。我们不关心记录集更新、删除等或任何废话。我们只想检索数据。我们获取该记录集,获取所有数据,然后将其删除。
问题 2:有没有更有效的方法来使用 ODBC 在 MFC 中检索数据?