65.9K
CodeProject 正在变化。 阅读更多。
Home

异步查询执行

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.50/5 (2投票s)

1999年12月9日

viewsIcon

83337

downloadIcon

806

提供异步 SQL 执行支持的两个类。

  • 下载源文件 - 7 Kb
  • 引言

    由于多线程支持可用,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 文档,异步处理会降低性能。

    © . All rights reserved.