Bagikan melalui


Eksekusi Asinkron (Metode Pemberitahuan)

ODBC memungkinkan eksekusi asinkron operasi koneksi dan pernyataan. Utas aplikasi dapat memanggil fungsi ODBC dalam mode asinkron dan fungsi dapat kembali sebelum operasi selesai, memungkinkan utas aplikasi untuk melakukan tugas lain. Di Windows 7 SDK, untuk pernyataan asinkron atau operasi koneksi, aplikasi menentukan bahwa operasi asinkron selesai menggunakan metode polling. Untuk informasi selengkapnya, lihat Eksekusi Asinkron (Metode Polling). Dimulai di Windows 8 SDK, Anda dapat menentukan bahwa operasi asinkron selesai menggunakan metode pemberitahuan.

Dalam metode polling, aplikasi perlu memanggil fungsi asinkron setiap kali menginginkan status operasi. Metode pemberitahuan mirip dengan panggilan balik dan menunggu di ADO.NET. Namun, ODBC menggunakan peristiwa Win32 sebagai objek pemberitahuan.

Pustaka Kursor ODBC dan pemberitahuan asinkron ODBC tidak dapat digunakan secara bersamaan. Pengaturan kedua atribut akan mengembalikan kesalahan dengan SQLSTATE S1119 (Pustaka Kursor dan Pemberitahuan Asinkron tidak dapat diaktifkan pada saat yang sama).

Lihat Pemberitahuan Penyelesaian Fungsi Asinkron untuk informasi bagi pengembang driver.

Catatan

Metode pemberitahuan tidak didukung dengan pustaka kursor. Aplikasi akan menerima pesan kesalahan jika mencoba mengaktifkan pustaka kursor melalui SQLSet Koneksi Attr, saat metode pemberitahuan diaktifkan.

Gambaran Umum

Ketika fungsi ODBC dipanggil dalam mode asinkron, kontrol dikembalikan ke aplikasi panggilan segera dengan kode pengembalian SQL_STILL_EXECUTING. Aplikasi harus berulang kali melakukan polling fungsi sampai mengembalikan sesuatu selain SQL_STILL_EXECUTING. Perulangan polling meningkatkan pemanfaatan CPU, menyebabkan performa yang buruk dalam banyak skenario asinkron.

Setiap kali model pemberitahuan digunakan, model polling dinonaktifkan. Aplikasi tidak boleh memanggil fungsi asli lagi. Panggil Fungsi SQLCompleteAsync untuk menyelesaikan operasi asinkron. Jika aplikasi memanggil fungsi asli lagi sebelum operasi asinkron selesai, panggilan akan mengembalikan SQL_ERROR dengan SQLSTATE IM017 (Polling dinonaktifkan dalam Mode Pemberitahuan Asinkron).

Saat menggunakan model pemberitahuan, aplikasi dapat memanggil SQLCancel atau SQLCancelHandle untuk membatalkan pernyataan atau operasi koneksi. Jika permintaan pembatalan berhasil, ODBC akan mengembalikan SQL_SUCCESS. Pesan ini tidak menunjukkan bahwa fungsi benar-benar dibatalkan; ini menunjukkan bahwa permintaan pembatalan diproses. Apakah fungsi benar-benar dibatalkan bergantung pada driver dan bergantung pada sumber data. Ketika operasi dibatalkan, Driver Manager masih akan memberi sinyal peristiwa. Driver Manager mengembalikan SQL_ERROR dalam buffer kode pengembalian dan statusnya adalah SQLSTATE HY008 (Operasi dibatalkan) untuk menunjukkan bahwa pembatalan berhasil. Jika fungsi menyelesaikan pemrosesan normalnya, Driver Manager mengembalikan SQL_SUCCESS atau SQL_SUCCESS_WITH_INFO.

Perilaku Tingkat Bawah

Versi Odbc Driver Manager yang mendukung pemberitahuan ini selesai adalah ODBC 3.81.

Versi ODBC Aplikasi Versi Manajer Driver Versi Driver Perilaku
Aplikasi baru dari versi ODBC apa pun ODBC 3.81 ODBC 3.80 Driver Aplikasi dapat menggunakan fitur ini jika driver mendukung fitur ini, jika tidak, Manajer Driver akan melakukan kesalahan.
Aplikasi baru dari versi ODBC apa pun ODBC 3.81 Driver Pra-ODBC 3.80 Manajer Driver akan melakukan kesalahan jika driver tidak mendukung fitur ini.
Aplikasi baru dari versi ODBC apa pun Pra-ODBC 3.81 Mana pun Ketika aplikasi menggunakan fitur ini, Driver Manager lama akan menganggap atribut baru sebagai atribut khusus driver, dan driver harus mengalami kesalahan. Manajer Driver baru tidak akan meneruskan atribut ini ke driver.

Aplikasi harus memeriksa versi Driver Manager sebelum menggunakan fitur ini. Jika tidak, jika driver yang ditulis dengan buruk tidak mengalami kesalahan dan versi Driver Manager adalah pra ODBC 3.81, perilaku tidak terdefinisi.

Kasus Penggunaan

Bagian ini menunjukkan kasus penggunaan untuk eksekusi asinkron dan mekanisme polling.

Mengintegrasikan Data dari Beberapa Sumber ODBC

Aplikasi integrasi data secara asinkron mengambil data dari beberapa sumber data. Beberapa data berasal dari sumber data jarak jauh dan beberapa data berasal dari file lokal. Aplikasi tidak dapat dilanjutkan hingga operasi asinkron selesai.

Alih-alih berulang kali melakukan polling operasi untuk menentukan apakah operasi selesai, aplikasi dapat membuat objek peristiwa dan mengaitkannya dengan handel koneksi ODBC atau handel pernyataan ODBC. Aplikasi kemudian memanggil API sinkronisasi sistem operasi untuk menunggu pada satu objek peristiwa atau banyak objek peristiwa (peristiwa ODBC dan peristiwa Windows lainnya). ODBC akan memberi sinyal objek peristiwa ketika operasi asinkron ODBC yang sesuai selesai.

Di Windows, objek peristiwa Win32 akan digunakan dan yang akan memberi pengguna model pemrograman terpadu. Driver Manager di platform lain dapat menggunakan implementasi objek peristiwa khusus untuk platform tersebut.

Sampel kode berikut menunjukkan penggunaan koneksi dan pemberitahuan asinkron pernyataan:

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

Menentukan apakah Driver Mendukung Pemberitahuan Asinkron

Aplikasi ODBC dapat menentukan apakah driver ODBC mendukung pemberitahuan asinkron dengan memanggil SQLGetInfo. Driver Manager ODBC akan memanggil SQLGetInfo driver dengan 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  
      }  
}  

Mengaitkan Handel Peristiwa Win32 dengan Handel ODBC

Aplikasi bertanggung jawab untuk membuat objek peristiwa Win32 menggunakan fungsi Win32 yang sesuai. Aplikasi dapat mengaitkan satu handel peristiwa Win32 dengan satu handel koneksi ODBC atau satu handel pernyataan ODBC.

atribut Koneksi ion SQL_ATTR_ASYNC_DBC_FUNCTION_ENABLE dan SQL_ATTR_ASYNC_DBC_EVENT menentukan apakah ODBC dijalankan dalam mode asinkron dan apakah ODBC mengaktifkan mode pemberitahuan untuk handel koneksi. Atribut pernyataan SQL_ATTR_ASYNC_ENABLE dan SQL_ATTR_ASYNC_STMT_EVENT menentukan apakah ODBC dijalankan dalam mode asinkron dan apakah ODBC mengaktifkan mode pemberitahuan untuk handel pernyataan.

SQL_ATTR_ASYNC_ENABLE atau SQL_ATTR_ASYNC_DBC_FUNCTION_ENABLE SQL_ATTR_ASYNC_STMT_EVENT atau SQL_ATTR_ASYNC_DBC_EVENT Mode
Aktifkan non-null Pemberitahuan Asinkron
Aktifkan nihil Polling Asinkron
Nonaktifkan any Sinkron

Aplikasi dapat menonaktifkan mode operasi asinkron secara sementara. ODBC mengabaikan nilai SQL_ATTR_ASYNC_DBC_EVENT jika operasi asinkron tingkat koneksi dinonaktifkan. ODBC mengabaikan nilai SQL_ATTR_ASYNC_STMT_EVENT jika operasi asinkron tingkat pernyataan dinonaktifkan.

Panggilan sinkron SQLSetStmtAttr dan SQLSet Koneksi Attr

  • SQLSet Koneksi Attr mendukung operasi asinkron tetapi pemanggilan SQLSet Koneksi Attr untuk mengatur SQL_ATTR_ASYNC_DBC_EVENT selalu sinkron.

  • SQLSetStmtAttr tidak mendukung eksekusi asinkron.

Skenario error-out
Ketika SQLSet Koneksi Attr dipanggil sebelum membuat koneksi, Manajer Driver tidak dapat menentukan driver mana yang akan digunakan. Oleh karena itu, Driver Manager mengembalikan keberhasilan untuk SQLSet Koneksi Attr tetapi atribut mungkin tidak siap untuk diatur dalam driver. Driver Manager akan mengatur atribut ini ketika aplikasi memanggil fungsi koneksi. Manajer Driver mungkin error-out karena driver tidak mendukung operasi asinkron.

Pewarisan atribut koneksi
Biasanya, pernyataan koneksi akan mewarisi atribut koneksi. Namun, atribut SQL_ATTR_ASYNC_DBC_EVENT tidak dapat diwariskan dan hanya memengaruhi operasi koneksi.

Untuk mengaitkan penanganan aktivitas dengan handel koneksi ODBC, aplikasi ODBC memanggil ODBC API SQLSet Koneksi Attr dan menentukan SQL_ATTR_ASYNC_DBC_EVENT sebagai atribut dan penanganan peristiwa sebagai nilai atribut. Atribut ODBC baru SQL_ATTR_ASYNC_DBC_EVENT berjenis SQL_IS_POINTER.

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

Biasanya, aplikasi membuat objek peristiwa reset otomatis. ODBC tidak akan mengatur ulang objek peristiwa. Aplikasi harus memastikan bahwa objek tidak dalam status sinyal sebelum memanggil fungsi ODBC asinkron apa pun.

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 adalah atribut khusus Driver Manager yang tidak akan diatur dalam driver.

Nilai default SQL_ATTR_ASYNC_DBC_EVENT adalah NULL. Jika driver tidak mendukung pemberitahuan asinkron, mendapatkan atau mengatur SQL_ATTR_ASYNC_DBC_EVENT akan mengembalikan SQL_ERROR dengan SQLSTATE HY092 (Pengidentifikasi atribut/opsi tidak valid).

Jika nilai SQL_ATTR_ASYNC_DBC_EVENT terakhir yang ditetapkan pada handel koneksi ODBC bukan NULL dan mode asinkron yang diaktifkan aplikasi dengan mengatur atribut SQL_ATTR_ASYNC_DBC_FUNCTION_ENABLE dengan SQL_ASYNC_DBC_ENABLE_ON, memanggil fungsi koneksi ODBC apa pun yang mendukung mode asinkron akan mendapatkan pemberitahuan penyelesaian. Jika nilai SQL_ATTR_ASYNC_DBC_EVENT terakhir yang ditetapkan pada handel koneksi ODBC adalah NULL, ODBC tidak akan mengirim pemberitahuan apa pun kepada aplikasi, terlepas dari apakah mode asinkron diaktifkan.

Aplikasi dapat mengatur SQL_ATTR_ASYNC_DBC_EVENT sebelum atau sesudah mengatur atribut SQL_ATTR_ASYNC_DBC_FUNCTION_ENABLE.

Aplikasi dapat mengatur atribut SQL_ATTR_ASYNC_DBC_EVENT pada handel koneksi ODBC sebelum memanggil fungsi koneksi (SQL Koneksi, SQLBrowse Koneksi, atau SQLDriver Koneksi). Karena Odbc Driver Manager tidak tahu driver ODBC mana yang akan digunakan aplikasi, itu akan mengembalikan SQL_SUCCESS. Ketika aplikasi memanggil fungsi koneksi, Odbc Driver Manager akan memeriksa apakah driver mendukung pemberitahuan asinkron. Jika driver tidak mendukung pemberitahuan asinkron, Manajer Driver ODBC akan mengembalikan SQL_ERROR dengan S1_118 SQLSTATE (Driver tidak mendukung pemberitahuan asinkron). Jika driver mendukung pemberitahuan asinkron, Odbc Driver Manager akan memanggil driver dan mengatur atribut yang sesuai SQL_ATTR_ASYNC_DBC_NOTIFICATION_CALLBACK dan SQL_ATTR_ASYNC_DBC_NOTIFICATION_CONTEXT.

Demikian pula, aplikasi memanggil SQLSetStmtAttr pada handel pernyataan ODBC dan menentukan atribut SQL_ATTR_ASYNC_STMT_EVENT untuk mengaktifkan atau menonaktifkan pemberitahuan asinkron tingkat pernyataan. Karena fungsi pernyataan selalu dipanggil setelah koneksi dibuat, SQLSetStmtAttr akan mengembalikan SQL_ERROR dengan S1_118 SQLSTATE (Driver tidak mendukung pemberitahuan asinkron) segera jika driver yang sesuai tidak mendukung operasi asinkron atau driver mendukung operasi asinkron tetapi tidak mendukung pemberitahuan asinkron.

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, yang dapat diatur ke NULL, adalah atribut khusus Manajer Driver yang tidak akan diatur dalam driver.

Nilai default SQL_ATTR_ASYNC_STMT_EVENT adalah NULL. Jika driver tidak mendukung pemberitahuan asinkron, mendapatkan atau mengatur atribut SQL_ATTR_ASYNC_ STMT_EVENT akan mengembalikan SQL_ERROR dengan SQLSTATE HY092 (Pengidentifikasi atribut/opsi tidak valid).

Aplikasi tidak boleh mengaitkan penanganan peristiwa yang sama dengan lebih dari satu handel ODBC. Jika tidak, satu pemberitahuan akan hilang jika dua pemanggilan fungsi ODBC asinkron selesai pada dua handel yang berbagi handel peristiwa yang sama. Untuk menghindari handel pernyataan yang mewarisi penanganan aktivitas yang sama dari handel koneksi, ODBC mengembalikan SQL_ERROR dengan SQLSTATE IM016 (Tidak dapat mengatur atribut pernyataan ke dalam handel koneksi) jika aplikasi mengatur SQL_ATTR_ASYNC_STMT_EVENT pada handel koneksi.

Memanggil Fungsi ODBC Asinkron

Setelah mengaktifkan pemberitahuan asinkron dan memulai operasi asinkron, aplikasi dapat memanggil fungsi ODBC apa pun. Jika fungsi milik kumpulan fungsi yang mendukung operasi asinkron, aplikasi akan mendapatkan pemberitahuan penyelesaian ketika operasi selesai, terlepas dari apakah fungsi gagal atau berhasil. Satu-satunya pengecualian adalah bahwa aplikasi memanggil fungsi ODBC dengan pegangan koneksi atau pernyataan yang tidak valid. Dalam hal ini, ODBC tidak akan mendapatkan handel peristiwa dan mengaturnya ke status yang disinyalir.

Aplikasi harus memastikan bahwa objek peristiwa terkait dalam status tidak diberi sinyal sebelum memulai operasi asinkron pada handel ODBC yang sesuai. ODBC tidak akan mengatur ulang objek peristiwa.

Mendapatkan Pemberitahuan dari ODBC

Utas aplikasi dapat memanggil WaitForSingleObject untuk menunggu pada satu handel peristiwa atau memanggil WaitForMultipleObjects untuk menunggu array handel peristiwa dan ditangguhkan hingga satu atau semua objek peristiwa menjadi sinyal atau interval waktu habis berlalu.

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