异步查询执行






4.50/5 (2投票s)
1999年12月9日

83337

806
提供异步 SQL 执行支持的两个类。
引言
由于多线程支持可用,MFC ODBC 类不再使用异步处理。 默认情况下,驱动程序同步执行 ODBC 函数;也就是说,应用程序调用一个函数,驱动程序在完成执行该函数之前不会将控制权返回给应用程序。 但是,某些函数可以异步执行;也就是说,应用程序调用该函数,驱动程序在进行最少的处理后,将控制权返回给应用程序。 应用程序可以在第一个函数仍在执行时调用其他函数。
大多数主要在数据源上执行的函数都支持异步执行,例如准备和执行 SQL 语句、检索元数据和获取数据的函数。 当在数据源上执行的任务需要很长时间时,例如针对大型数据库的复杂查询,它最有用。
在 MFC 4.2 及更高版本中,允许异步执行的 `CDatabase::SetSynchronousMode()` 函数已过时。 MFC ODBC 类现在仅使用同步处理。
`CAsyncDatabase` 和 `CAsyncRecordset` 两个类提供对异步执行的支持。 这允许应用程序在执行复杂查询时执行其他任务。
用法非常简单。 将 CAsyncDatabase.* 和 CAsyncRecordset.* 文件复制到项目中。 不要忘记
#include "AsyncDatabase.h" #include "AsyncRecordset.h"
检查以下示例
对于 CAsyncDatabase
- 像往常一样打开数据库;
- 调用 `ExecuteSQLAsync(<sql_query_text_here>);`
- 调用 CAsyncDatabase 的 `SQLStillExecuting()` 来确定查询是否仍在执行;
- 使用 `ExecuteSQLAsync()` 返回的 HSTMT 调用 CDatabase 的 `Cancel()` 函数以取消查询执行。
CAsyncDatabase 示例
// asynchronous query execution void ExecuteLongQuery(strQuery) { CAsyncDatabase DB; DB.OpenEx(""); HSTMT hstmt = DB.ExecuteSQLAsync(strQuery); // complex query while(DB.SQLStillExecuting(hstmt)) { // check for Cancel command, for exmpl _GET_MESSAGE_ if(Cancelled()) // by Cancel button, for example { DB.Cancel(hstmt); return; } } }
对于 CAsyncRecordset
- 使用 `OpenAsync(...)` 打开记录集。(参数与 `Open()` 相同);
- 调用 CAsyncRecordset 的 `StillExecuting()` 来确定查询是否仍在执行;
- 调用 CRecordset 的 `Cancel()` 函数以取消记录集打开(即 SELECT 查询执行)。
CAsyncRecordset 示例
// Open Asynchronous Recordset { // DB is a CDatabase CAsyncRecordset rs(&DB); rs.OpenAsync(CRecordset::snapshot, strQuery, CRecordset::executeDirect); while(rs.StillExecuting()) { _GET_MESSAGE_ if(Cancelled()) { rs.Cancel(); rs.Close(); return; } } if(!rs.IsOpen()) return; else ContinueTask(); // perform some task rs.Close(); }
关于 OnSetOptions() 虚拟函数的一些说明
框架调用此成员函数来设置记录集或数据库的初始选项。 `CRecordset` 和 `CDatabase` 的 `OnSetOptions()` 确定数据源对可滚动游标和游标并发的支持,并相应地设置记录集的选项。
您可以覆盖 OnSetOptions() 以设置特定于驱动程序或数据源的其他选项。 例如,如果您的数据源支持以独占方式打开,您可以覆盖 `OnSetOptions()` 以利用该功能。
CAsyncDatabase 和 CAsyncRecordset 类使用 OnSetOptions() 来确定数据源对异步函数执行的支持,并相应地设置选项。(如果数据源不支持异步执行,`CAsyncDatabase` 和 `CAsyncRecordset` 都会同步执行函数,而不警告用户。) 因此,当您覆盖 `OnSetOptions()` 时,请务必从派生类的 `OnSetOptions()` 调用 `CAsyncDatabase::OnSetOptions()` 或 `CAsyncRecordset::OnSetOptions()`。
注意:根据 MFC 文档,异步处理会降低性能。