非同期実行 (通知方法)Asynchronous Execution (Notification Method)

ODBC では、接続とステートメントの操作の非同期実行を許可します。ODBC allows asynchronous execution of connection and statement operations. アプリケーション スレッドで非同期モードで ODBC 関数を呼び出すことができ、操作が完了すると、その他のタスクを実行するアプリケーションのスレッドを許可する前に、関数が返すことができます。An application thread can call an ODBC function in asynchronous mode and the function can return before the operation is complete, allowing the application thread to perform other tasks. Windows 7 sdk の非同期ステートメントまたは接続操作では、アプリケーションは、非同期操作が完了のポーリング メソッドを使用して決定されます。In the Windows 7 SDK, for asynchronous statement or connection operations, an application determined that the asynchronous operation was complete using the polling method. 詳細については、次を参照してください。非同期実行 (ポーリング メソッド)します。For more information, see Asynchronous Execution (Polling Method). 以降、Windows 8 SDK では、非同期操作が通知メソッドを使用して完全なことを確認できます。Beginning in the Windows 8 SDK, you can determine that an asynchronous operation is complete using the notification method.

ポーリング メソッドでは、アプリケーションが操作の状態が必要があるたびに、非同期関数を呼び出す必要があります。In the polling method, applications need to call the asynchronous function each time it wants the status of the operation. 通知方法は、コールバックと ADO.NET での待機に似ています。The notification method is similar to callback and wait in ADO.NET. ODBC では、通知オブジェクトとしてただし、Win32 イベントを使用します。ODBC, however, uses Win32 events as the notification object.

ODBC カーソル ライブラリおよび ODBC 非同期通知を同時に使用できません。The ODBC Cursor Library and ODBC asynchronous notification cannot be used at the same time. 両方の属性を設定すると、SQLSTATE S1119 でエラーが返されます (カーソル ライブラリと非同期の通知を有効にできません同時)。Setting both attributes will return an error with SQLSTATE S1119 (Cursor Library and Asynchronous Notification cannot be enabled at the same time).

参照してください非同期の関数の完了の通知ドライバー開発者向けの情報にします。See Notification of Asynchronous Function Completion for information for driver developers.

注意

カーソル ライブラリでは、通知方法はサポートされていません。The notification method is not supported with cursor library. アプリケーションと通知方法を有効にすると、SQLSetConnectAttr を使用してカーソル ライブラリを有効にするとエラー メッセージが表示されます。An application will receive error message if it attempts to enable cursor library via SQLSetConnectAttr, when the notification method is enabled.

概要Overview

非同期モードで ODBC 関数が呼び出されると、コントロールが SQL_STILL_EXECUTING のリターン コードですぐに呼び出し元アプリケーションに返されます。When an ODBC function is called in asynchronous mode, the control is returned to the calling application immediately with the return code SQL_STILL_EXECUTING. アプリケーションは、関数を SQL_STILL_EXECUTING 以外に返されるまでポーリング繰り返し必要があります。The application must repeatedly poll the function until it returns something other than SQL_STILL_EXECUTING. ポーリング ループでは、多くの非同期のシナリオでパフォーマンスの低下の原因と、CPU 使用率が向上します。The polling loop increases CPU utilization, causing poor performance in many asynchronous scenarios.

通知のモデルを使用すると、常にポーリング モデルが無効です。Whenever the notification model is used, the polling model is disabled. アプリケーションでは、元の関数を再度呼び出さないでください。Applications should not call the original function again. 呼び出すSQLCompleteAsync 関数非同期操作を完了します。Call SQLCompleteAsync Function to complete the asynchronous operation. 呼び出しで SQL_ERROR SQLSTATE IM017 が返す場合、アプリケーションは、非同期操作が完了する前にもう一度、元の関数を呼び出す、(非同期の通知モードでのポーリングは無効です)。If an application calls the original function again before the asynchronous operation is complete, the call will return SQL_ERROR with SQLSTATE IM017 (Polling is disabled in Asynchronous Notification Mode).

通知のモデルを使用する場合、アプリケーションを呼び出すことができますSQLCancelまたはSQLCancelHandleステートメントまたは接続の操作をキャンセルします。When using the notification model, the application can call SQLCancel or SQLCancelHandle to cancel a statement or connection operation. 取り消し要求が成功した場合、ODBC は SQL_SUCCESS を返します。If the cancel request is successful, ODBC will return SQL_SUCCESS. このメッセージは、関数が実際にキャンセルされたことを示していませんこれは、キャンセル要求が処理されたことを示します。This message does not indicate that the function was actually canceled; it indicates that the cancel request was processed. 関数が実際に取り消されたかどうかは、ドライバーに依存し、データ ソースに依存します。Whether the function is actually canceled is driver-dependent and data source-dependent. 操作が取り消されたときに、ドライバー マネージャーは引き続きイベントを通知します。When an operation is canceled, the Driver Manager will still signal the event. ドライバー マネージャーは、リターン コードのバッファーで SQL_ERROR を返し、状態が SQLSTATE HY008 (操作が取り消されました) を示す、キャンセルに成功しました。The Driver Manager returns SQL_ERROR in the return code buffer and the state is SQLSTATE HY008 (Operation canceled) to indicate the cancelation is successful. 関数には、通常の処理が完了したら、ドライバー マネージャーは SQL_SUCCESS または SQL_SUCCESS_WITH_INFO を返します。If the function completed its normal processing, the Driver Manager returns SQL_SUCCESS or SQL_SUCCESS_WITH_INFO.

ダウンレベルの動作Downlevel Behavior

完全にこの通知をサポートしている ODBC ドライバー マネージャーのバージョンでは、ODBC 3.81 です。The ODBC Driver Manager version supporting this notification on complete is ODBC 3.81.

アプリケーションの ODBC のバージョンApplication ODBC Version ドライバー マネージャーのバージョンDriver Manager Version ドライバーのバージョンDriver Version 動作Behavior
任意の ODBC バージョンの新しいアプリケーションNew application of any ODBC version ODBC 3.81ODBC 3.81 3.80 の ODBC ドライバーODBC 3.80 Driver それ以外の場合、ドライバー マネージャーはエラーになります、ドライバーは、この機能をサポートしている場合、アプリケーションはこの機能を使用できます。Application can use this feature if the driver supports this feature, otherwise the Driver Manager will error out.
任意の ODBC バージョンの新しいアプリケーションNew application of any ODBC version ODBC 3.81ODBC 3.81 3.80 の以前の ODBC ドライバーPre-ODBC 3.80 Driver ドライバー マネージャー、ドライバーはこの機能をサポートしていないをエラーになります。The Driver Manager will error out if the driver does not support this feature.
任意の ODBC バージョンの新しいアプリケーションNew application of any ODBC version プレ ODBC 3.81Pre-ODBC 3.81 AnyAny アプリケーションでは、この機能を使用して、古いドライバー マネージャーがドライバー固有の属性として、新しい属性をとらえますドライバーにエラーが発生する必要があります。新しいドライバー マネージャーがドライバーにこれらの属性を渡しません。When the application uses this feature, an old Driver Manager will regard the new attributes as driver-specific attributes, and the driver should error out. A new Driver Manager will not pass these attributes to the driver.

アプリケーションでは、この機能を使用する前に、ドライバー マネージャーのバージョンを確認する必要があります。An application should check the Driver Manager version before using this feature. それ以外の場合、不完全ドライバーがエラーではなくは、ドライバー マネージャーのバージョンが以前の ODBC 3.81、動作は定義されません。Otherwise, if a poorly written driver does not error out and the Driver Manager version is pre ODBC 3.81, behavior is undefined.

ユース ケースUse Cases

このセクションでは、非同期実行し、ポーリング メカニズムの使用例を示します。This section shows use cases for asynchronous execution and the polling mechanism.

複数の ODBC ソースからデータを統合します。Integrate Data from Multiple ODBC Sources

データ統合アプリケーションは、複数のデータ ソースから非同期的にデータをフェッチします。A data integration application asynchronously fetches data from multiple data sources. リモート データ ソースからデータの一部は、いくつかのデータはローカル ファイルから.Some of the data are from remote data sources and some data are from local files. アプリケーションは、非同期操作が完了するまで続行できません。The application cannot continue until the asynchronous operations are completed.

完了するための操作を繰り返しポーリングではなく、アプリケーションでイベント オブジェクトを作成および ODBC 接続ハンドルまたは ODBC ステートメント ハンドルに関連付けること。Instead of repeatedly polling an operation to determine if it is complete, the application can create an event object and associate it with an ODBC connection handle or an ODBC statement handle. その後、アプリケーションでは、オペレーティング システムの同期イベントを 1 つ以上の多くのイベント オブジェクト (ODBC のイベントとその他の Windows イベントの両方) 上で待機する Api を呼び出します。The application then calls operating system synchronization APIs to wait on one event object or many event objects (both ODBC events and other Windows events). ODBC は、対応する ODBC 非同期操作が完了したときに、イベント オブジェクトに通知します。ODBC will signal the event object when the corresponding ODBC asynchronous operation is completed.

Windows、Win32 イベント オブジェクトが使用され、統一されたプログラミング モデルが提供します。On Windows, Win32 event objects will be used and that will provide the user a unified programming model. その他のプラットフォーム上のドライバー マネージャーは、これらのプラットフォームに固有のイベント オブジェクトの実装を使用できます。Driver Managers on other platforms can use the event object implementation specific to those platforms.

次のコード サンプルでは、接続とステートメントの非同期通知の使用を示しています。The following code sample demonstrates the use of connection and statement asynchronous notification:

// This function opens NUMBER_OPERATIONS connections and executes one query on statement of each connection.  
// Asynchronous Notification is used  
  
#define NUMBER_OPERATIONS 5  
int AsyncNotificationSample(void)  
{  
    RETCODE     rc;  
  
    SQLHENV     hEnv              = NULL;  
    SQLHDBC     arhDbc[NUMBER_OPERATIONS]         = {NULL};  
    SQLHSTMT    arhStmt[NUMBER_OPERATIONS]        = {NULL};  
  
    HANDLE      arhDBCEvent[NUMBER_OPERATIONS]    = {NULL};  
    RETCODE     arrcDBC[NUMBER_OPERATIONS]        = {0};  
    HANDLE      arhSTMTEvent[NUMBER_OPERATIONS]   = {NULL};  
    RETCODE     arrcSTMT[NUMBER_OPERATIONS]       = {0};  
  
    rc = SQLAllocHandle(SQL_HANDLE_ENV, NULL, &hEnv);  
    if ( !SQL_SUCCEEDED(rc) ) goto Cleanup;  
  
    rc = SQLSetEnvAttr(hEnv,  
        SQL_ATTR_ODBC_VERSION,  
        (SQLPOINTER) SQL_OV_ODBC3_80,  
        SQL_IS_INTEGER);  
    if ( !SQL_SUCCEEDED(rc) ) goto Cleanup;  
  
    // Connection operations begin here  
  
    // Alloc NUMBER_OPERATIONS connection handles  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        rc = SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &arhDbc[i]);  
        if ( !SQL_SUCCEEDED(rc) ) goto Cleanup;  
    }  
  
    // Enable DBC Async on all connection handles  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        rc= SQLSetConnectAttr(arhDbc[i], SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE, (SQLPOINTER)SQL_ASYNC_DBC_ENABLE_ON, SQL_IS_INTEGER);  
        if ( !SQL_SUCCEEDED(rc) ) goto Cleanup;  
    }  
  
    // Application must create event objects  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        arhDBCEvent[i] = CreateEvent(NULL, FALSE, FALSE, NULL); // Auto-reset, initial state is not-signaled  
        if (!arhDBCEvent[i]) goto Cleanup;  
    }  
  
    // Enable notification on all connection handles  
    // Event  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        rc= SQLSetConnectAttr(arhDbc[i], SQL_ATTR_ASYNC_DBC_EVENT, arhDBCEvent[i], SQL_IS_POINTER);  
        if ( !SQL_SUCCEEDED(rc) ) goto Cleanup;  
    }  
  
    // Initiate connect establishing  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        SQLDriverConnect(arhDbc[i], NULL, (SQLTCHAR*)TEXT("Driver={ODBC Driver 11 for SQL Server};SERVER=dp-srv-sql2k;DATABASE=pubs;UID=sa;PWD=XYZ;"), SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT);  
    }  
  
    // Can do some other staff before calling WaitForMultipleObjects  
    WaitForMultipleObjects(NUMBER_OPERATIONS, arhDBCEvent, TRUE, INFINITE); // Wait All  
  
    // Complete connect API calls  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        SQLCompleteAsync(SQL_HANDLE_DBC, arhDbc[i], & arrcDBC[i]);  
    }  
  
    BOOL fFail = FALSE; // Whether some connection openning fails.  
  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        if ( !SQL_SUCCEEDED(arrcDBC[i]) )   
            fFail = TRUE;  
    }  
  
    // If some SQLDriverConnect() fail, clean up.  
    if (fFail)  
    {  
        for (int i=0; i<NUMBER_OPERATIONS; i++)  
        {  
            if (SQL_SUCCEEDED(arrcDBC[i]) )   
            {  
                SQLDisconnect(arhDbc[i]); // This is also async  
            }  
            else  
            {  
                SetEvent(arhDBCEvent[i]); // Previous SQLDriverConnect() failed. No need to call SQLDisconnect().  
            }  
        }  
        WaitForMultipleObjects(NUMBER_OPERATIONS, arhDBCEvent, TRUE, INFINITE);   
        for (int i=0; i<NUMBER_OPERATIONS; i++)  
        {  
            if (SQL_SUCCEEDED(arrcDBC[i]) )   
            {     
                SQLCompleteAsync(SQL_HANDLE_DBC, arhDbc[i], &arrcDBC[i]);; // To Complete  
            }  
        }  
  
        goto Cleanup;  
    }  
  
    // Statement Operations begin here  
  
    // Alloc statement handle  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        rc = SQLAllocHandle(SQL_HANDLE_STMT, arhDbc[i], &arhStmt[i]);  
        if ( !SQL_SUCCEEDED(rc) ) goto Cleanup;  
    }  
  
    // Enable STMT Async on all statement handles  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        rc = SQLSetStmtAttr(arhStmt[i], SQL_ATTR_ASYNC_ENABLE, (SQLPOINTER)SQL_ASYNC_ENABLE_ON, SQL_IS_INTEGER);  
        if ( !SQL_SUCCEEDED(rc) ) goto Cleanup;  
    }  
  
    // Create event objects  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        arhSTMTEvent[i] = CreateEvent(NULL, FALSE, FALSE, NULL); // Auto-reset, initial state is not-signaled  
        if (!arhSTMTEvent[i]) goto Cleanup;  
    }  
  
    // Enable notification on all statement handles  
    // Event  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        rc= SQLSetStmtAttr(arhStmt[i], SQL_ATTR_ASYNC_STMT_EVENT, arhSTMTEvent[i], SQL_IS_POINTER);  
        if ( !SQL_SUCCEEDED(rc) ) goto Cleanup;  
    }  
  
    // Initiate SQLExecDirect() calls  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        SQLExecDirect(arhStmt[i], (SQLTCHAR*)TEXT("select au_lname, au_fname from authors"), SQL_NTS);  
    }  
  
    // Can do some other staff before calling WaitForMultipleObjects  
    WaitForMultipleObjects(NUMBER_OPERATIONS, arhSTMTEvent, TRUE, INFINITE); // Wait All  
  
    // Now, call SQLCompleteAsync to complete the operation and get return code  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        SQLCompleteAsync(SQL_HANDLE_STMT, arhStmt[i], &arrcSTMT[i]);  
    }  
  
    // Check return values  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        if ( !SQL_SUCCEEDED(arrcSTMT[i]) ) goto Cleanup;  
    }  
  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        //Do some binding jobs here, set SQL_ATTR_ROW_ARRAY_SIZE   
    }  
  
    // Now, initiate fetching  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        SQLFetch(arhStmt[i]);  
    }  
  
    // Can do some other staff before calling WaitForMultipleObjects  
    WaitForMultipleObjects(NUMBER_OPERATIONS, arhSTMTEvent, TRUE, INFINITE);   
  
    // Now, to complete the operations and get return code  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        SQLCompleteAsync(SQL_HANDLE_STMT, arhStmt[i], &arrcSTMT[i]);  
    }  
  
    // Check return code  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        if ( !SQL_SUCCEEDED(arrcSTMT[i]) ) goto Cleanup;  
    }  
  
    // USE fetched data here!!  
  
Cleanup:  
  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        if (arhStmt[NUMBER_OPERATIONS])  
        {  
            SQLFreeHandle(SQL_HANDLE_STMT, arhStmt[i]);  
            arhStmt[i] = NULL;  
        }  
    }  
  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        if (arhSTMTEvent[i])  
        {  
            CloseHandle(arhSTMTEvent[i]);  
            arhSTMTEvent[i] = NULL;  
        }  
    }  
  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        if (arhDbc[i])  
        {  
            SQLFreeHandle(SQL_HANDLE_DBC, arhDbc[i]);  
            arhDbc[i] = NULL;  
        }  
    }  
  
    for (int i=0; i<NUMBER_OPERATIONS; i++)  
    {  
        if (arhDBCEvent[i])  
        {  
            CloseHandle(arhDBCEvent[i]);  
            arhDBCEvent[i] = NULL;  
        }  
    }  
  
    if (hEnv)  
    {  
        SQLFreeHandle(SQL_HANDLE_ENV, hEnv);  
        hEnv = NULL;  
    }  
  
    return 0;  
}  
  

ドライバーが非同期通知をサポートしているかを決定します。Determining if a Driver Supports Asynchronous Notification

ODBC アプリケーションが呼び出すことによって、ODBC ドライバーが非同期通知をサポートしているかを判断することができますSQLGetInfoします。An ODBC application can determine if an ODBC driver supports asynchronous notification by calling SQLGetInfo. ODBC ドライバー マネージャーを呼び出す、その結果、 SQLGetInfo SQL_ASYNC_NOTIFICATION とドライバーの。The ODBC Driver Manager will consequently call the SQLGetInfo of the driver with SQL_ASYNC_NOTIFICATION.

SQLUINTEGER InfoValue;  
SQLLEN      cbInfoLength;  
  
SQLRETURN retcode;  
retcode = SQLGetInfo (hDbc,   
                      SQL_ASYNC_NOTIFICATION,   
                      &InfoValue,  
                      sizeof(InfoValue),  
                      NULL);  
if (SQL_SUCCEEDED(retcode))  
{  
if (SQL_ASYNC_NOTIFICATION_CAPABLE == InfoValue)  
      {  
          // The driver supports asynchronous notification  
      }  
      else if (SQL_ASYNC_NOTIFICATION_NOT_CAPABLE == InfoValue)  
      {  
          // The driver does not support asynchronous notification  
      }  
}  

ODBC ハンドルを Win32 イベント ハンドルを関連付けるAssociating a Win32 Event Handle with an ODBC Handle

アプリケーションは、対応する Win32 関数を使用して Win32 イベント オブジェクトを作成する責任を負います。Applications are responsible for creating Win32 event objects using the corresponding Win32 functions. アプリケーションでは、1 つの ODBC 接続ハンドルや ODBC ステートメント ハンドルの 1 つで 1 つの Win32 イベント ハンドルを関連付けることができます。An application can associate one Win32 event handle with one ODBC connection handle or one ODBC statement handle.

接続属性 SQL_ATTR_ASYNC_DBC_FUNCTION_ENABLE および SQL_ATTR_ASYNC_DBC_EVENT は、ODBC が非同期モードで実行するかどうかと、ODBC 接続ハンドルの通知モードを有効にするかどうかを決定します。Connection attributes SQL_ATTR_ASYNC_DBC_FUNCTION_ENABLE and SQL_ATTR_ASYNC_DBC_EVENT determine whether ODBC executes in asynchronous mode and whether ODBC enables notification mode for a connection handle. SQL_ATTR_ASYNC_ENABLE と SQL_ATTR_ASYNC_STMT_EVENT ステートメント属性は、ODBC が非同期モードで実行するかどうかと、ODBC ステートメント ハンドルの通知モードを有効にするかどうかを決定します。Statement attributes SQL_ATTR_ASYNC_ENABLE and SQL_ATTR_ASYNC_STMT_EVENT determine whether ODBC executes in asynchronous mode and whether ODBC enables notification mode for a statement handle.

SQL_ATTR_ASYNC_ENABLE または SQL_ATTR_ASYNC_DBC_FUNCTION_ENABLESQL_ATTR_ASYNC_ENABLE or SQL_ATTR_ASYNC_DBC_FUNCTION_ENABLE SQL_ATTR_ASYNC_STMT_EVENT または SQL_ATTR_ASYNC_DBC_EVENTSQL_ATTR_ASYNC_STMT_EVENT or SQL_ATTR_ASYNC_DBC_EVENT モードMode
[有効化]Enable null 以外non-null 非同期通知Asynchronous Notification
[有効化]Enable nullnull 非同期ポーリングAsynchronous Polling
DisableDisable anyany 同期Synchronous

アプリケーションは、非同期の操作モードを無効に一時的にできます。An application can temporally disable asynchronous operation mode. ODBC では、接続レベルの非同期操作が無効になっている場合、SQL_ATTR_ASYNC_DBC_EVENT の値が無視されます。ODBC ignores values of SQL_ATTR_ASYNC_DBC_EVENT if the connection level asynchronous operation is disabled. ODBC では、ステートメント レベルの非同期操作が無効になっている場合、SQL_ATTR_ASYNC_STMT_EVENT の値が無視されます。ODBC ignores values of SQL_ATTR_ASYNC_STMT_EVENT if the statement level asynchronous operation is disabled.

同期呼び出しのSQLSetStmtAttrSQLSetConnectAttrSynchronous call of SQLSetStmtAttr and SQLSetConnectAttr

  • SQLSetConnectAttr非同期操作の呼び出しでは、 SQLSetConnectAttr SQL_ATTR_ASYNC_DBC_EVENT を設定するのには同期では常にします。SQLSetConnectAttr supports asynchronous operations but the invocation of SQLSetConnectAttr to set SQL_ATTR_ASYNC_DBC_EVENT is always synchronous.

  • SQLSetStmtAttr非同期実行をサポートしていません。SQLSetStmtAttr does not support asynchronous execution.

エラー アウト シナリオError-out scenario
ときにSQLSetConnectAttr接続をドライバー マネージャーは使用するドライバーを特定できませんを行う前に呼び出されます。When SQLSetConnectAttr is called before making a connection, the Driver Manager cannot determine which driver to use. そのため、ドライバー マネージャーがの成功を返しますSQLSetConnectAttrが属性が、ドライバーで設定する準備ができていない可能性があります。Therefore, the Driver Manager returns success for SQLSetConnectAttr but the attribute may not be ready to set in the driver. ドライバー マネージャーは、アプリケーションが接続関数を呼び出すときにこれらの属性を設定します。The Driver Manager will set these attributes when the application calls a connection function. ドライバー マネージャーには、ドライバーでは、非同期操作をサポートしていないため、エラー出力が可能性があります。The Driver Manager may error-out because driver does not support asynchronous operations.

接続属性の継承Inheritance of connection attributes
通常、接続のステートメントは、接続属性を継承します。Usually, the statements of a connection will inherit the connection attributes. ただし、SQL_ATTR_ASYNC_DBC_EVENT 属性は継承できませんし、接続操作にのみ影響します。However, the attribute SQL_ATTR_ASYNC_DBC_EVENT is not inheritable and only affects the connection operations.

ODBC 接続ハンドルにイベント ハンドルを関連付けるには、ODBC アプリケーションは ODBC API を呼び出します。 SQLSetConnectAttr SQL_ATTR_ASYNC_DBC_EVENT を属性の値として処理する属性と、イベントを指定します。To associate an event handle with an ODBC connection handle, an ODBC application calls ODBC API SQLSetConnectAttr and specifies SQL_ATTR_ASYNC_DBC_EVENT as the attribute and the event handle as the attribute value. 新しい ODBC 属性 SQL_ATTR_ASYNC_DBC_EVENT は型 SQL_IS_POINTER です。The new ODBC attribute SQL_ATTR_ASYNC_DBC_EVENT is of type SQL_IS_POINTER.

HANDLE hEvent;  
hEvent = CreateEvent(   
            NULL,                // default security attributes  
            FALSE,               // auto-reset event  
            FALSE,               // initial state is non-signaled  
            NULL                 // no name  
            );  

通常、アプリケーションは、自動リセット イベント オブジェクトを作成します。Usually, applications create auto-reset event objects. ODBC では、イベント オブジェクトはリセットされません。ODBC will not reset the event object. アプリケーションで必要があります、あるオブジェクトはシグナル状態に非同期 ODBC 関数を呼び出す前に確認します。Applications must make sure that the object is not in signaled state before calling any asynchronous ODBC function.

SQLRETURN retcode;  
retcode = SQLSetConnectAttr ( hDBC,  
                              SQL_ATTR_ASYNC_DBC_EVENT, // Attribute name  
                              (SQLPOINTER) hEvent,      // Win32 Event handle  
                              SQL_IS_POINTER);          // Length Indicator  

SQL_ATTR_ASYNC_DBC_EVENT は、ドライバー マネージャー専用の属性で、ドライバーでは設定されません。SQL_ATTR_ASYNC_DBC_EVENT is a Driver Manager-only attribute that will not be set in the driver.

SQL_ATTR_ASYNC_DBC_EVENT の既定値は、NULL です。The default value of SQL_ATTR_ASYNC_DBC_EVENT is NULL. 取得または設定 SQL_ATTR_ASYNC_DBC_EVENT が SQLSTATE HY092 SQL_ERROR を返します、ドライバーが非同期通知をサポートしていない場合 (無効な属性またはオプション識別子)。If the driver does not support asynchronous notification, getting or setting SQL_ATTR_ASYNC_DBC_EVENT will return SQL_ERROR with SQLSTATE HY092 (Invalid attribute/option identifier).

ODBC 接続ハンドルが NULL でないと、アプリケーション SQL_ATTR_ASYNC_DBC_FUNCTION_ENABLE SQL_ASYNC_DBC_ENABLE_ON、任意の ODBC 接続を呼び出すことで属性を設定して非同期モードを有効になっている SQL_ATTR_ASYNC_DBC_EVENT の最後の値の設定の場合非同期モードをサポートしている関数の完了通知が表示されます。If the last SQL_ATTR_ASYNC_DBC_EVENT value set on an ODBC connection handle is not NULL and the application enabled asynchronous mode by setting attribute SQL_ATTR_ASYNC_DBC_FUNCTION_ENABLE with SQL_ASYNC_DBC_ENABLE_ON, calling any ODBC connection function that supports asynchronous mode will get a completion notification. ODBC 接続ハンドルで設定された最後 SQL_ATTR_ASYNC_DBC_EVENT 値が NULL の場合は、ODBC は送信しません、アプリケーション、任意の通知に関係なく非同期モードが有効になっているかどうか。If the last SQL_ATTR_ASYNC_DBC_EVENT value set on an ODBC connection handle is NULL, ODBC will not send the application any notification, regardless whether asynchronous mode is enabled.

アプリケーションは前に、または SQL_ATTR_ASYNC_DBC_FUNCTION_ENABLE 属性を設定した後、SQL_ATTR_ASYNC_DBC_EVENT を設定できます。An application can set SQL_ATTR_ASYNC_DBC_EVENT before or after setting the attribute SQL_ATTR_ASYNC_DBC_FUNCTION_ENABLE.

アプリケーションは接続関数を呼び出す前に ODBC 接続ハンドルの SQL_ATTR_ASYNC_DBC_EVENT 属性を設定することができます (SQLConnectSQLBrowseConnect、またはSQLDriverConnect)。Applications can set the SQL_ATTR_ASYNC_DBC_EVENT attribute on an ODBC connection handle before calling a connection function (SQLConnect, SQLBrowseConnect, or SQLDriverConnect). ODBC ドライバー マネージャーが、アプリケーションで使用する ODBC ドライバーを知らないので、SQL_SUCCESS が返されます。Because the ODBC Driver Manager does not know which ODBC driver the application will use, it will return SQL_SUCCESS. アプリケーションが接続関数を呼び出すと、ODBC ドライバー マネージャーは、ドライバーが非同期通知をサポートしているかどうかを確認します。When the application calls a connection function, the ODBC Driver Manager will check whether the driver supports asynchronous notification. ドライバーが非同期通知をサポートしていない場合、ODBC ドライバー マネージャーは SQLSTATE S1_118 SQL_ERROR を返します (ドライバーは非同期通知をサポートしていません)。If the driver does not support asynchronous notification, the ODBC Driver Manager will return SQL_ERROR with SQLSTATE S1_118 (Driver does not support asynchronous notification). ドライバーは、非同期通知をサポートする場合、ODBC ドライバー マネージャーがドライバーを呼び出すし、SQL_ATTR_ASYNC_DBC_NOTIFICATION_CALLBACK と SQL_ATTR_ASYNC_DBC_NOTIFICATION_CONTEXT に対応する属性を設定します。If the driver supports asynchronous notification, the ODBC Driver Manager will call the driver and set the corresponding attributes SQL_ATTR_ASYNC_DBC_NOTIFICATION_CALLBACK and SQL_ATTR_ASYNC_DBC_NOTIFICATION_CONTEXT.

アプリケーションを呼び出すと同様に、 SQLSetStmtAttr ODBC ステートメントで処理し、有効またはステートメント レベルの非同期通知を無効にする SQL_ATTR_ASYNC_STMT_EVENT 属性を指定します。Similarly, an application calls SQLSetStmtAttr on an ODBC statement handle and specifies the SQL_ATTR_ASYNC_STMT_EVENT attribute to enable or disable statement level asynchronous notification. 接続が確立されると、常にステートメントの関数が呼び出されるためSQLSetStmtAttr SQLSTATE S1_118 SQL_ERROR が返されます (ドライバーは非同期通知をサポートしていない) 場合にすぐに、対応します。ドライバーは非同期操作をサポートしていないか、ドライバーは、非同期操作をサポートしていますが、非同期通知をサポートしていません。Because a statement function is always called after the connection is established, SQLSetStmtAttr will return SQL_ERROR with SQLSTATE S1_118 (Driver does not support asynchronous notification) immediately if the corresponding driver does not support asynchronous operations or the driver supports asynchronous operation but does not support asynchronous notification.

SQLRETURN retcode;  
retcode = SQLSetStmtAttr ( hSTMT,  
                           SQL_ATTR_ASYNC_STMT_EVENT, // Attribute name   
                           (SQLPOINTER) hEvent,       // Win32 Event handle  
                           SQL_IS_POINTER);           // length Indicator  

SQL_ATTR_ASYNC_STMT_EVENT で、NULL に設定することができますは、ドライバー マネージャー専用の属性で、ドライバーでは設定されません。SQL_ATTR_ASYNC_STMT_EVENT, which can be set to NULL, is a Driver Manager-only attribute that will not be set in the driver.

SQL_ATTR_ASYNC_STMT_EVENT の既定値は、NULL です。The default value of SQL_ATTR_ASYNC_STMT_EVENT is NULL. 取得または設定 SQL_ATTR_ASYNC_ STMT_EVENT 属性が SQLSTATE HY092 SQL_ERROR を返します、ドライバーが非同期通知をサポートしていない場合 (無効な属性またはオプション識別子)。If the driver does not support asynchronous notification, getting or setting the SQL_ATTR_ASYNC_ STMT_EVENT attribute will return SQL_ERROR with SQLSTATE HY092 (Invalid attribute/option identifier).

アプリケーションは、ODBC ハンドルの 1 つ以上を同じイベント ハンドルを関連付けないでする必要があります。An application should not associate the same event handle with more than one ODBC handle. それ以外の場合、同じイベント ハンドルを共有する 2 つのハンドルに 2 つの非同期の ODBC 関数呼び出しを完了すると、1 つの通知は失われます。Otherwise, one notification will be lost if two asynchronous ODBC function invocations complete on two handles that share the same event handle. 接続ハンドルから、同じイベント ハンドルを継承する、ステートメント ハンドルを避けるためには、ODBC は、アプリケーションは、接続ハンドルの SQL_ATTR_ASYNC_STMT_EVENT を設定する場合 (接続ハンドルにステートメント属性を設定できません)、SQLSTATE IM016 SQL_ERROR を返します。To avoid a statement handle inheriting the same event handle from the connection handle, ODBC returns SQL_ERROR with SQLSTATE IM016 (Cannot set statement attribute into connection handle) if an application sets SQL_ATTR_ASYNC_STMT_EVENT on a connection handle.

非同期の ODBC 関数を呼び出しCalling Asynchronous ODBC Functions

非同期通知を有効にすると、非同期操作を開始、アプリケーションは、任意の ODBC 関数を呼び出すことができます。After enabling asynchronous notification and starting an asynchronous operation, the application can call any ODBC function. 非同期操作をサポートする関数のセットに属する場合、アプリケーションまたは表示されます完了通知、操作が完了したら、関数が失敗したかどうかに関係なくに成功しました。If the function belongs to the set of functions that support asynchronous operation, the application will get a completion notification when the operation completes, regardless of whether the function failed or succeeded. 唯一の例外は、アプリケーションが無効な接続やステートメント ハンドルで ODBC 関数を呼び出します。The only exception is that the application calls an ODBC function with an invalid connection or statement handle. この場合は、ODBC がイベント ハンドルを取得しない、およびシグナル状態に設定されます。In this case, ODBC will not get the event handle and set it to the signaled state.

アプリケーションは、対応する ODBC ハンドルでの非同期操作を開始する前に、関連付けられているイベント オブジェクトが、非シグナル状態にことを確認する必要があります。The application must ensure that the associated event object is in a non-signaled state before starting an asynchronous operation on the corresponding ODBC handle. ODBC では、イベント オブジェクトはリセットされません。ODBC will not reset the event object.

ODBC からの通知の取得Getting Notification from ODBC

アプリケーション スレッドを呼び出すことができますWaitForSingleObject 1 つのイベントのハンドルまたは呼び出しの待機にWaitForMultipleObjectsイベント ハンドルの配列を待機し、1 つまたはすべてのイベント オブジェクトまで中断されますシグナル状態になるか、タイムアウト間隔が経過しました。An application thread can call WaitForSingleObject to wait on one event handle or call WaitForMultipleObjects to wait on an array of event handles and be suspended until one or all of the event objects become signaled or the time-out interval elapses.

DWORD dwStatus = WaitForSingleObject(  
                        hEvent,  // The event associated with the ODBC handle  
                        5000     // timeout is 5000 millisecond   
);  
  
If (dwStatus == WAIT_TIMEOUT)  
{  
    // time-out interval elapsed before all the events are signaled.   
}  
Else  
{  
    // Call the corresponding Asynchronous ODBC API to complete all processing and retrieve the return code.  
}