Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
ODBC, bağlantı ve deyim işlemlerinin zaman uyumsuz yürütülmesine izin verir. Uygulama iş parçacığı bir ODBC işlevini zaman uyumsuz modda çağırabilir ve işlev işlem tamamlanmadan önce döndürülerek uygulama iş parçacığının diğer görevleri gerçekleştirmesine olanak tanır. Windows 7 SDK'si içinde, eş zamansız ifade veya bağlantı işlemleri için uygulama, yoklama yöntemi kullanarak eş zamansız işlemin tamamlandığını belirledi. Daha fazla bilgi için bkz. Zaman Uyumsuz Yürütme (Yoklama Yöntemi). Windows 8 SDK'sında başlayarak, bildirim yöntemini kullanarak zaman uyumsuz bir işlemin tamamlandığını belirleyebilirsiniz.
Yoklama yönteminde, uygulamaların işlemin durumunu her istediğinde zaman uyumsuz işlevi çağırması gerekir. Bildirim yöntemi, ADO.NET'te geri çağırma ve bekleme yöntemlerine benzerdir. Ancak ODBC, bildirim nesnesi olarak Win32 olaylarını kullanır.
ODBC İmleç Kitaplığı ve ODBC zaman uyumsuz bildirimi aynı anda kullanılamaz. Her iki özniteliğin ayarlanması SQLSTATE S1119 ile ilgili bir hata döndürür (İmleç Kitaplığı ve Zaman Uyumsuz Bildirim aynı anda etkinleştirilemez).
Sürücü geliştiricileri için bilgi için bkz. Zaman Uyumsuz İşlev Tamamlama bildirimi.
Not
Bildirim yöntemi imleç kitaplığında desteklenmez. Uygulama, bildirim yöntemi etkinleştirildiğinde SQLSetConnectAttr aracılığıyla imleç kitaplığını etkinleştirmeye çalışırsa hata iletisi alır.
Genel bakış
Bir ODBC işlevi zaman uyumsuz modda çağrıldığında, kontrol hemen dönüş kodu SQL_STILL_EXECUTING ile çağıran uygulamaya geri döner. Uygulama, SQL_STILL_EXECUTING dışında bir şey döndürene kadar işlevi tekrar tekrar yoklamalıdır. Yoklama döngüsü CPU kullanımını artırarak birçok zaman uyumsuz senaryoda düşük performansa neden olur.
Bildirim modeli her kullanıldığında yoklama modeli devre dışı bırakılır. Uygulamalar özgün işlevi yeniden çağırmamalıdır. Zaman uyumsuz işlemi tamamlamak için SQLCompleteAsync İşlevi
Bildirim modelini kullanırken, uygulama bir deyimi veya bağlantı işlemini iptal etmek için SQLCancel veya SQLCancelHandle çağırabilir. İptal isteği başarılı olursa, ODBC SQL_SUCCESS döndürür. Bu ileti işlevin gerçekten iptal edilmiş olduğunu göstermez; iptal isteğinin işlendiğini gösterir. İşlevin gerçekten iptal edilip edilmediği sürücüye ve veri kaynağına bağımlıdır. Bir işlem iptal edildiğinde, Sürücü Yöneticisi yine de olaya işaret eder. Sürücü Yöneticisi, dönüş kodu arabelleğinde SQL_ERROR döner ve iptalin başarılı olduğunu belirtmek için durum kodu olarak SQLSTATE HY008 (İşlem iptal edildi) verir. İşlev normal işlemesini tamamladıysa Sürücü Yöneticisi SQL_SUCCESS veya SQL_SUCCESS_WITH_INFO döndürür.
Alt Düzey Davranışı
Bu bildirimi tam olarak destekleyen ODBC Sürücü Yöneticisi sürümü ODBC 3.81'dir.
| Uygulama ODBC Sürümü | Sürücü Yöneticisi Sürümü | Sürücü Sürümü | Davranış |
|---|---|---|---|
| Herhangi bir ODBC sürümünün yeni uygulaması | ODBC 3.81 | ODBC 3.80 Sürücüsü | Sürücü bu özelliği destekliyorsa uygulama bu özelliği kullanabilir, aksi takdirde Sürücü Yöneticisi hata verir. |
| Herhangi bir ODBC sürümünün yeni uygulaması | ODBC 3.81 | ODBC 3.80 Öncesi Sürücü | Sürücü bu özelliği desteklemiyorsa Sürücü Yöneticisi hata alır. |
| Herhangi bir ODBC sürümünün yeni uygulaması | ODBC Öncesi 3.81 | Herhangi | Uygulama bu özelliği kullandığında, eski bir Sürücü Yöneticisi yeni öznitelikleri sürücüye özgü öznitelikler olarak değerlendirir ve sürücünün hata verebilir. Yeni bir Sürücü Yöneticisi ise bu öznitelikleri sürücüye iletmez. |
Bu özelliği kullanmadan önce bir uygulamanın Driver Manager sürümünü denetlemesi gerekir. Aksi takdirde, kötü yazılmış bir sürücü hata vermezse ve Driver Manager sürümü ODBC 3.81 öncesiyse, davranış tanımlanmamıştır.
Kullanım Örnekleri
Bu bölümde, zaman uyumsuz yürütme ve yoklama mekanizması için kullanım örnekleri gösterilmektedir.
Birden Çok ODBC Kaynağından Verileri Tümleştirme
Veri tümleştirme uygulaması birden çok veri kaynağından zaman uyumsuz olarak veri getirir. Verilerin bazıları uzak veri kaynaklarından, bazıları yerel dosyalardandır. Zaman uyumsuz işlemler tamamlanana kadar uygulama devam edemez.
Tamamlanıp tamamlanmadığını belirlemek için bir işlemi tekrar tekrar yoklama yerine, uygulama bir olay nesnesi oluşturabilir ve bunu bir ODBC bağlantı tutamacı veya ODBC deyimi tanıtıcısıyla ilişkilendirebilir. Uygulama daha sonra işletim sistemi eşitleme API'lerini çağırarak bir olay nesnesi veya birçok olay nesnesi (hem ODBC olayları hem de diğer Windows olayları) üzerinde bekler. ODBC, ilgili ODBC zaman uyumsuz işlemi tamamlandığında olay nesnesine sinyal gönderir.
Windows'da Win32 olay nesneleri kullanılır ve kullanıcıya birleşik bir programlama modeli sağlar. Diğer platformlardaki Sürücü Yöneticileri, bu platformlara özgü olay nesnesi uygulamasını kullanabilir.
Aşağıdaki kod örneği, bağlantı ve ifade zaman uyumsuz bildiriminin kullanımını gösterir.
// 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;
}
Sürücünün Zaman Uyumsuz Bildirimi Desteklediğini Belirleme
ODBC uygulaması, SQLGetInfoçağrısı yaparak ODBC sürücüsünün zaman uyumsuz bildirimi desteklenip desteklemediğini belirleyebilir. ODBC Sürücü Yöneticisi, SQL_ASYNC_NOTIFICATION ile sürücünün SQLGetInfo fonksiyonunu sonuç olarak çağıracaktır.
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
}
}
Win32 Olay İşleyicisini ODBC Tutamacı ile İlişkileştirme
Uygulamalar, karşılık gelen Win32 işlevlerini kullanarak Win32 olay nesneleri oluşturmakla sorumludur. Bir uygulama, bir Win32 olay tutamacını bir ODBC bağlantı tutamacı veya bir ODBC deyimi tutamacı ile ilişkilendirebilir.
bağlantı öznitelikleri SQL_ATTR_ASYNC_DBC_FUNCTION_ENABLE ve SQL_ATTR_ASYNC_DBC_EVENT ODBC'nin zaman uyumsuz modda yürütülip yürütülmeyeceğini ve ODBC'nin bağlantı tutamacı için bildirim modunu etkinleştirip etkinleştirmediğini belirler. deyim öznitelikleri SQL_ATTR_ASYNC_ENABLE ve SQL_ATTR_ASYNC_STMT_EVENT ODBC'nin zaman uyumsuz modda yürütülip yürütülmeyeceğini ve ODBC'nin bir deyim tanıtıcısı için bildirim modunu etkinleştirip etkinleştirmediğini belirler.
| SQL_ATTR_ASYNC_ENABLE veya SQL_ATTR_ASYNC_DBC_FUNCTION_ENABLE | SQL_ATTR_ASYNC_STMT_EVENT veya SQL_ATTR_ASYNC_DBC_EVENT | Mod |
|---|---|---|
| Etkinleştir | null olmayan | Asenkron Bildirim |
| Etkinleştir | sıfır | Asenkron Yoklama |
| Devre dışı bırakmak | herhangi | Eşzamanlı |
Bir uygulama, zaman uyumsuz işlem modunu geçici olarak devre dışı bırakabilir. Bağlantı düzeyi zaman uyumsuz işlem devre dışı bırakılırsa ODBC, SQL_ATTR_ASYNC_DBC_EVENT değerlerini yoksayar. İfade düzeyi eşzamanlı olmayan işlem devre dışı bırakılırsa ODBC, SQL_ATTR_ASYNC_STMT_EVENT değerlerini yoksayar.
SQLSetStmtAttr ve SQLSetConnectAttr senkron çağrısı
SQLSetConnectAttr, zaman uyumsuz işlemleri destekler, ancak SQL_ATTR_ASYNC_DBC_EVENT ayarlamak için SQLSetConnectAttr çağrısı her zaman eşzamanlıdır.
SQLSetStmtAttr zaman uyumsuz yürütmeyi desteklemez.
Hata ile sonuçlanan senaryo
Bağlantı kurmadan önce SQLSetConnectAttr
Bağlantı özniteliklerinin devralınma
Genellikle, bağlantı deyimleri bağlantı özniteliklerini devralır. Ancak, SQL_ATTR_ASYNC_DBC_EVENT özniteliği devralınamaz ve yalnızca bağlantı işlemlerini etkiler.
Bir olay tutamacını ODBC bağlantı tutamacıyla ilişkilendirmek için, ODBC uygulaması SQLSetConnectAttr
HANDLE hEvent;
hEvent = CreateEvent(
NULL, // default security attributes
FALSE, // auto-reset event
FALSE, // initial state is non-signaled
NULL // no name
);
Genellikle, uygulamalar otomatik sıfırlama olay nesneleri oluşturur. ODBC, olay nesnesini sıfırlamaz. Uygulamalar, herhangi bir zaman uyumsuz ODBC işlevini çağırmadan önce nesnenin sinyalli durumda olmadığından emin olmalıdır.
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, sürücüde ayarlanmayacak yalnızca Sürücü Yöneticisi özniteliğidir.
SQL_ATTR_ASYNC_DBC_EVENT varsayılan değeri NULL'dir. Sürücü zaman uyumsuz bildirimi desteklemiyorsa, SQL_ATTR_ASYNC_DBC_EVENT'i almak veya ayarlamak, SQLSTATE HY092 (Geçersiz öznitelik/seçenek tanımlayıcısı) ile birlikte SQL_ERROR döndürür.
ODBC bağlantı tanıtıcısında ayarlanan son SQL_ATTR_ASYNC_DBC_EVENT değeri NULL değilse ve uygulama SQL_ASYNC_DBC_ENABLE_ON ile öznitelik SQL_ATTR_ASYNC_DBC_FUNCTION_ENABLE ayarlayarak zaman uyumsuz modu etkinleştirdiyse, zaman uyumsuz modu destekleyen herhangi bir ODBC bağlantı işlevini çağırmak bir tamamlama bildirimi alır. ODBC bağlantı tanıtıcısında ayarlanan son SQL_ATTR_ASYNC_DBC_EVENT değeri NULL ise, ODBC zaman uyumsuz modun etkinleştirilip etkinleştirilmediğine bakılmaksızın uygulamaya herhangi bir bildirim göndermez.
Bir uygulama SQL_ATTR_ASYNC_DBC_FUNCTION_ENABLE özniteliğini ayarlamadan önce veya sonra SQL_ATTR_ASYNC_DBC_EVENT ayarlayabilir.
Uygulamalar, bir bağlantı işlevini çağırmadan önce ODBC bağlantı tanıtıcısında SQL_ATTR_ASYNC_DBC_EVENT özniteliğini ayarlayabilir ( SQLConnect, SQLBrowseConnectveya SQLDriverConnect). ODBC Sürücü Yöneticisi uygulamanın hangi ODBC sürücüsünü kullanacağını bilmediğinden SQL_SUCCESS döndürür. Uygulama bir bağlantı işlevini çağırdığında, ODBC Sürücü Yöneticisi sürücünün zaman uyumsuz bildirimi destekleyip desteklemediğini denetler. Sürücü zaman uyumsuz bildirimi desteklemiyorsa, ODBC Sürücü Yöneticisi SQLSTATE S1_118 ile SQL_ERROR döndürür (Sürücü zaman uyumsuz bildirimi desteklemez). Sürücü zaman uyumsuz bildirimi destekliyorsa, ODBC Sürücü Yöneticisi sürücüyü çağırır ve ilgili öznitelikleri SQL_ATTR_ASYNC_DBC_NOTIFICATION_CALLBACK ve SQL_ATTR_ASYNC_DBC_NOTIFICATION_CONTEXT ayarlar.
Benzer şekilde, bir uygulama ODBC deyim tanıtıcısında SQLSetStmtAttr çağırır ve deyim düzeyinde zaman uyumsuz bildirimi etkinleştirmek veya devre dışı bırakmak için SQL_ATTR_ASYNC_STMT_EVENT özniteliğini belirtir. Bağlantı kurulduktan sonra her zaman bir deyim işlevi çağrıldığından, SQLSetStmtAttr, ilgili sürücü ya zaman uyumsuz işlemleri desteklemiyorsa veya zaman uyumsuz işlemleri destekliyorsa ancak zaman uyumsuz bildirimleri desteklemiyorsa, SQLSTATE S1_118 (Sürücü zaman uyumsuz bildirimi desteklemez) ile SQL_ERROR döndürür.
SQLRETURN retcode;
retcode = SQLSetStmtAttr ( hSTMT,
SQL_ATTR_ASYNC_STMT_EVENT, // Attribute name
(SQLPOINTER) hEvent, // Win32 Event handle
SQL_IS_POINTER); // length Indicator
NULL olarak ayarlanabilen SQL_ATTR_ASYNC_STMT_EVENT, sürücüde ayarlanmayacak yalnızca Sürücü Yöneticisi özniteliğidir.
SQL_ATTR_ASYNC_STMT_EVENT varsayılan değeri NULL'dir. Sürücü zaman uyumsuz bildirimi desteklemiyorsa, SQL_ATTR_ASYNC_STMT_EVENT özniteliğini almak veya ayarlamak, SQLSTATE HY092 (Geçersiz öznitelik/seçenek tanımlayıcısı) ile SQL_ERROR döndürür.
Bir uygulama aynı olay tutamacını birden fazla ODBC tutamacı ile ilişkilendirmemelidir. Aksi takdirde, aynı olay tutamacını paylaşan iki tanıtıcıda iki zaman uyumsuz ODBC işlevi çağrısı tamamlandığında bir bildirim kaybolur. Bir uygulama bağlantı tutamacına SQL_ATTR_ASYNC_STMT_EVENT ayarlarsa, bir deyim tanıtıcısının bağlantı tutamacından aynı olay tanıtıcısını devralmasını önlemek için ODBC, SQLSTATE IM016 (Bağlantı tutamacına deyim özniteliği ayarlanamaz) ile SQL_ERROR döndürür.
Zaman Uyumsuz ODBC İşlevlerini Çağırma
Zaman uyumsuz bildirimi etkinleştirdikten ve zaman uyumsuz bir işlem başlattıktan sonra uygulama herhangi bir ODBC işlevini çağırabilir. İşlev, zaman uyumsuz işlemi destekleyen işlev kümesine aitse, işlev başarısız veya başarılı olup olmadığına bakılmaksızın işlem tamamlandığında uygulama bir tamamlama bildirimi alır. Tek istisna, uygulamanın geçersiz bir bağlantı veya deyim tanıtıcısı olan bir ODBC işlevini çağırmasıdır. Bu durumda, ODBC ne olay tutamacını alır ne de onu sinyalli duruma ayarlar.
Uygulamanın ilgili ODBC tanıtıcısında zaman uyumsuz bir işlem başlatmadan önce ilişkili olay nesnesinin sinyalsiz durumda olduğundan emin olması gerekir. ODBC, olay nesnesini sıfırlamaz.
ODBC'den Bildirim Alma
Bir uygulama iş parçacığı, bir olay tanıtıcısında beklemek için WaitForSingleObject veya bir dizi olay tanıtıcısını beklemek için WaitForMultipleObjects çağrısını yapabilir ve olay nesnelerinden biri veya tümü sinyal verilene ya da zaman aşımı süresi dolana kadar askıda kalabilir.
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.
}