Delen via


Asynchrone uitvoering (meldingsmethode)

ODBC maakt asynchrone uitvoering van verbindings- en instructiebewerkingen mogelijk. Een toepassingsthread kan een ODBC-functie aanroepen in asynchrone modus en de functie kan worden geretourneerd voordat de bewerking is voltooid, zodat de toepassingsthread andere taken kan uitvoeren. In de Windows 7 SDK, voor asynchrone opdracht- of verbindingsbewerkingen, kon een toepassing bepalen dat de asynchrone bewerking was voltooid door de polling-methode. Zie Asynchrone uitvoering (pollingmethode) voor meer informatie. Vanaf de Windows 8 SDK kunt u bepalen dat een asynchrone bewerking is voltooid met behulp van de meldingsmethode.

In de polling-methode moeten toepassingen de asynchrone functie aanroepen telkens wanneer deze de status van de bewerking wil. De meldingsmethode is vergelijkbaar met callback en wachten in ADO.NET. ODBC gebruikt echter Win32-gebeurtenissen als het meldingsobject.

De ODBC Cursor Library en ODBC asynchrone melding kunnen niet tegelijkertijd worden gebruikt. Als u beide kenmerken instelt, wordt een fout geretourneerd met SQLSTATE S1119 (cursorbibliotheek en asynchrone melding kunnen niet tegelijkertijd worden ingeschakeld).

Zie De melding van Asynchrone functievoltooiing voor informatie voor stuurprogrammaontwikkelaars.

Opmerking

De meldingsmethode wordt niet ondersteund met cursorbibliotheek. Een toepassing ontvangt een foutbericht als de cursorbibliotheek via SQLSetConnectAttr wordt ingeschakeld wanneer de meldingsmethode is ingeschakeld.

Overzicht

Wanneer een ODBC-functie in asynchrone modus wordt aangeroepen, wordt het besturingselement onmiddellijk met de retourcode SQL_STILL_EXECUTING naar de aanroepende toepassing geretourneerd. De toepassing moet de functie herhaaldelijk pollen totdat deze iets anders retourneert dan SQL_STILL_EXECUTING. De polling-lus verhoogt het CPU-gebruik, wat leidt tot slechte prestaties in veel asynchrone scenario's.

Wanneer het meldingsmodel wordt gebruikt, wordt het polling-model uitgeschakeld. Toepassingen mogen de oorspronkelijke functie niet opnieuw aanroepen. Roep de functie SQLCompleteAsync aan om de asynchrone bewerking te voltooien. Als een toepassing de oorspronkelijke functie opnieuw aanroept voordat de asynchrone bewerking is voltooid, retourneert de aanroep SQL_ERROR met SQLSTATE IM017 (Polling is uitgeschakeld in de Asynchrone meldingsmodus).

Wanneer u het meldingsmodel gebruikt, kan de toepassing SQLCancel of SQLCancelHandle aanroepen om een instructie of verbindingsbewerking te annuleren. Als de annuleringsaanvraag is geslaagd, retourneert ODBC SQL_SUCCESS. Dit bericht geeft niet aan dat de functie daadwerkelijk is geannuleerd; hiermee wordt aangegeven dat de annuleringsaanvraag is verwerkt. Of de functie daadwerkelijk wordt geannuleerd, is afhankelijk van stuurprogramma's en gegevensbronafhankelijk. Wanneer een bewerking wordt geannuleerd, geeft Driver Manager de gebeurtenis nog steeds aan. Driver Manager retourneert SQL_ERROR in de retourcodebuffer en de status IS SQLSTATE HY008 (Bewerking geannuleerd) om aan te geven dat de annulering is geslaagd. Als de functie de normale verwerking heeft voltooid, retourneert Driver Manager SQL_SUCCESS of SQL_SUCCESS_WITH_INFO.

Gedrag op een lager niveau

De ODBC Driver Manager-versie die deze melding volledig ondersteunt, is ODBC 3.81.

ODBC-versie van applicatie Driver Manager-versie Stuurprogrammaversie Gedrag
Nieuwe toepassing van een ODBC-versie ODBC 3.81 ODBC 3.80-stuurprogramma De toepassing kan deze functie gebruiken als het stuurprogramma deze functie ondersteunt, anders wordt er een foutmelding weergegeven in Driver Manager.
Nieuwe toepassing van een ODBC-versie ODBC 3.81 Pre-ODBC 3.80-stuurprogramma Er wordt een foutmelding weergegeven als het stuurprogramma deze functie niet ondersteunt.
Nieuwe toepassing van een ODBC-versie Pre-ODBC 3.81 Welke dan ook Wanneer de toepassing deze functie gebruikt, zal een oud stuurprogrammabeheer de nieuwe kenmerken beschouwen als stuurprogrammaspecifieke kenmerken en moet het stuurprogramma een foutmelding krijgen. Een nieuwe Driver Manager geeft deze kenmerken niet door aan het stuurprogramma.

Een toepassing moet de versie van Driver Manager controleren voordat deze functie wordt gebruikt. Anders, als een slecht geschreven stuurprogramma geen foutmelding krijgt en de Driver Manager-versie voor ODBC 3.81 is, is het gedrag niet gedefinieerd.

Gebruiksvoorbeelden

In deze sectie ziet u use cases voor asynchrone uitvoering en het polling-mechanisme.

Gegevens uit meerdere ODBC-bronnen integreren

Een gegevensintegratietoepassing haalt asynchroon gegevens op uit meerdere gegevensbronnen. Sommige gegevens zijn afkomstig van externe gegevensbronnen en sommige gegevens zijn afkomstig uit lokale bestanden. De toepassing kan pas worden voortgezet als de asynchrone bewerkingen zijn voltooid.

In plaats van herhaaldelijk een bewerking te peilen om te bepalen of deze is voltooid, kan de toepassing een gebeurtenisobject maken en koppelen aan een ODBC-verbindingsgreep of een ODBC-instructiehandgreep. De toepassing roept vervolgens api's voor besturingssysteemsynchronisatie aan om te wachten op één gebeurtenisobject of veel gebeurtenisobjecten (zowel ODBC-gebeurtenissen als andere Windows-gebeurtenissen). ODBC geeft het gebeurtenisobject aan wanneer de bijbehorende ODBC-asynchrone bewerking is voltooid.

In Windows worden Win32-gebeurtenisobjecten gebruikt en die de gebruiker een uniform programmeermodel bieden. Stuurprogrammamanagers op andere platforms kunnen de implementatie van gebeurtenisobjecten gebruiken die specifiek zijn voor deze platforms.

In het volgende codevoorbeeld wordt gedemonstreerd hoe asynchrone meldingen voor verbindingen en opdrachten worden gebruikt.

// 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 opening 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;  
}  
  

Bepalen of een stuurprogramma Asynchrone melding ondersteunt

Een ODBC-toepassing kan bepalen of een ODBC-stuurprogramma asynchrone meldingen ondersteunt door SQLGetInfo aan te roepen. OdBC Driver Manager roept daarom de SQLGetInfo van het stuurprogramma aan met 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  
      }  
}  

Een Win32-eventhandle koppelen aan een ODBC-handle

Toepassingen zijn verantwoordelijk voor het maken van Win32-gebeurtenisobjecten met behulp van de bijbehorende Win32-functies. Een toepassing kan één Win32-gebeurtenisgreep koppelen aan één ODBC-verbindingsgreep of één ODBC-instructiegreep.

Verbindingskenmerken SQL_ATTR_ASYNC_DBC_FUNCTION_ENABLE en SQL_ATTR_ASYNC_DBC_EVENT bepalen of ODBC wordt uitgevoerd in asynchrone modus en of ODBC de meldingsmodus inschakelt voor een verbindingsgreep. Instructiekenmerken SQL_ATTR_ASYNC_ENABLE en SQL_ATTR_ASYNC_STMT_EVENT bepalen of ODBC wordt uitgevoerd in asynchrone modus en of ODBC de meldingsmodus inschakelt voor een instructiehandgreep.

SQL_ATTR_ASYNC_ENABLE of SQL_ATTR_ASYNC_DBC_FUNCTION_ENABLE SQL_ATTR_ASYNC_STMT_EVENT of SQL_ATTR_ASYNC_DBC_EVENT Wijze
Enable niet-null Asynchrone melding
Enable Nul Asynchrone polling
Disable any Synchronous

Een toepassing kan de asynchrone bewerkingsmodus tijdelijk uitschakelen. ODBC negeert waarden van SQL_ATTR_ASYNC_DBC_EVENT als de asynchrone bewerking op verbindingsniveau is uitgeschakeld. ODBC negeert waarden van SQL_ATTR_ASYNC_STMT_EVENT als de asynchrone bewerking op instructieniveau is uitgeschakeld.

Synchrone aanroep van SQLSetStmtAttr en SQLSetConnectAttr

  • SQLSetConnectAttr ondersteunt asynchrone bewerkingen, maar de aanroep van SQLSetConnectAttr voor het instellen van SQL_ATTR_ASYNC_DBC_EVENT is altijd synchroon.

  • SQLSetStmtAttr biedt geen ondersteuning voor asynchrone uitvoering.

Foutafhandelingsscenario
Wanneer SQLSetConnectAttr wordt aangeroepen voordat er verbinding wordt gemaakt, kan de Driver Manager niet bepalen welk stuurprogramma moet worden gebruikt. Daarom retourneert Driver Manager succes voor SQLSetConnectAttr , maar het kenmerk is mogelijk niet gereed om in het stuurprogramma in te stellen. De Driver Manager stelt deze kenmerken in wanneer de toepassing een verbindingsfunctie aanroept. Stuurprogrammabeheer kan fouten veroorzaken omdat het stuurprogramma geen asynchrone bewerkingen ondersteunt.

Overname van verbindingskenmerken
Normaal gesproken nemen de instructies van een verbinding de verbindingskenmerken over. Het kenmerk SQL_ATTR_ASYNC_DBC_EVENT is echter niet overgenomen en is alleen van invloed op de verbindingsbewerkingen.

Als u een gebeurtenisingang wilt koppelen aan een ODBC-verbindingsgreep, roept een ODBC-toepassing ODBC API SQLSetConnectAttr aan en geeft u SQL_ATTR_ASYNC_DBC_EVENT op als het kenmerk en de gebeurtenisgreep als de kenmerkwaarde. Het nieuwe ODBC-kenmerk SQL_ATTR_ASYNC_DBC_EVENT is van het 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  
            );  

Normaal gesproken creëren toepassingen auto-reset gebeurtenisobjecten. ODBC stelt het gebeurtenisobject niet opnieuw in. Toepassingen moeten ervoor zorgen dat het object zich niet in de gesignaleerde status bevindt voordat een asynchrone ODBC-functie wordt aangeroepen.

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 is een kenmerk dat alleen door de stuurprogrammabeheerder wordt gebruikt en dat niet in het stuurprogramma wordt ingesteld.

De standaardwaarde van SQL_ATTR_ASYNC_DBC_EVENT is NULL. Als het stuurprogramma geen asynchrone meldingen ondersteunt, zal het verkrijgen of instellen van SQL_ATTR_ASYNC_DBC_EVENT resulteren in SQL_ERROR met SQLSTATE HY092 (ongeldig attribuut-/optie-identificatie).

Als de laatste SQL_ATTR_ASYNC_DBC_EVENT waarde die is ingesteld op een ODBC-verbindingsgreep niet NULL is en de asynchrone modus van de toepassing is ingeschakeld door kenmerk SQL_ATTR_ASYNC_DBC_FUNCTION_ENABLE in te stellen met SQL_ASYNC_DBC_ENABLE_ON, krijgt het aanroepen van een ODBC-verbindingsfunctie die asynchrone modus ondersteunt, een voltooiingsmelding. Als de laatste SQL_ATTR_ASYNC_DBC_EVENT waarde die is ingesteld op een ODBC-verbindingsgreep NULL is, verzendt ODBC de toepassing geen melding, ongeacht of de asynchrone modus is ingeschakeld.

Een toepassing kan SQL_ATTR_ASYNC_DBC_EVENT instellen voor of na het instellen van het kenmerk SQL_ATTR_ASYNC_DBC_FUNCTION_ENABLE.

Toepassingen kunnen het SQL_ATTR_ASYNC_DBC_EVENT kenmerk instellen op een ODBC-verbindingsgreep voordat u een verbindingsfunctie aanroept (SQLConnect, SQLBrowseConnect of SQLDriverConnect). Omdat odbc-stuurprogrammabeheer niet weet welk ODBC-stuurprogramma de toepassing gaat gebruiken, wordt SQL_SUCCESS geretourneerd. Wanneer de toepassing een verbindingsfunctie aanroept, controleert ODBC Driver Manager of het stuurprogramma asynchrone meldingen ondersteunt. Als het stuurprogramma geen asynchrone melding ondersteunt, retourneert ODBC Driver Manager SQL_ERROR met SQLSTATE S1_118 (Stuurprogramma biedt geen ondersteuning voor asynchrone meldingen). Als het stuurprogramma asynchrone meldingen ondersteunt, roept ODBC-stuurprogrammabeheer het stuurprogramma aan en stelt u de bijbehorende kenmerken in SQL_ATTR_ASYNC_DBC_NOTIFICATION_CALLBACK en SQL_ATTR_ASYNC_DBC_NOTIFICATION_CONTEXT.

Op dezelfde manier roept een toepassing SQLSetStmtAttr aan op een ODBC-instructiehandgreep en geeft het SQL_ATTR_ASYNC_STMT_EVENT kenmerk op om asynchrone melding op instructieniveau in of uit te schakelen. Omdat een instructiefunctie altijd wordt aangeroepen nadat de verbinding tot stand is gebracht, retourneert SQLSetStmtAttr SQL_ERROR met SQLSTATE S1_118 (Stuurprogramma biedt geen ondersteuning voor asynchrone melding) onmiddellijk als het bijbehorende stuurprogramma geen asynchrone bewerkingen ondersteunt of het stuurprogramma asynchrone bewerkingen ondersteunt, maar geen asynchrone melding ondersteunt.

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, die kan worden ingesteld op NULL, is een alleen stuurprogrammabeheerkenmerk dat niet in het stuurprogramma wordt ingesteld.

De standaardwaarde van SQL_ATTR_ASYNC_STMT_EVENT is NULL. Als het stuurprogramma geen asynchrone melding ondersteunt, retourneert het verkrijgen of instellen van het kenmerk SQL_ATTR_ASYNC_ STMT_EVENT SQL_ERROR met SQLSTATE HY092 (ongeldig kenmerk/optie-id).

Een toepassing mag niet dezelfde gebeurtenis-handle koppelen aan meer dan één ODBC-ingang. Anders gaat één melding verloren als twee asynchrone ODBC-functieaanroepen zijn voltooid op twee handles die dezelfde gebeurtenishandle delen. Om te voorkomen dat een instructiegreep dezelfde gebeurtenisgreep over neemt van de verbindingsgreep, retourneert ODBC SQL_ERROR met SQLSTATE IM016 (Kan instructiekenmerk niet instellen in verbindingsgreep) als een toepassing SQL_ATTR_ASYNC_STMT_EVENT instelt op een verbindingsgreep.

Asynchrone ODBC-functies aanroepen

Nadat asynchrone meldingen zijn ingeschakeld en een asynchrone bewerking zijn gestart, kan de toepassing elke ODBC-functie aanroepen. Als de functie deel uitmaakt van de set functies die asynchrone bewerking ondersteunen, krijgt de toepassing een voltooiingsmelding wanneer de bewerking is voltooid, ongeacht of de functie is mislukt of geslaagd. De enige uitzondering hierop is dat de toepassing een ODBC-functie aanroept met een ongeldige verbinding of instructiegreep. In dit geval krijgt ODBC de gebeurtenis-handle niet en stelt deze in op de gesignaleerde status.

De toepassing moet ervoor zorgen dat het bijbehorende gebeurtenisobject zich in een niet-gesignaleerde status bevindt voordat u een asynchrone bewerking start op de bijbehorende ODBC-ingang. ODBC stelt het gebeurtenisobject niet opnieuw in.

Melding ontvangen van ODBC

Een toepassingsthread kan WaitForSingleObject aanroepen om te wachten op één gebeurtenishandle of WaitForMultipleObjects aanroepen om te wachten op een array van gebeurtenishandles en worden opgeschort totdat een of alle gebeurtenisobjecten gesignaleerd worden of het time-out-interval is verstreken.

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.  
}