unxiODBC編程(五)錯誤處理
訪問www.tomcoding.com網站,學習Oracle內部數據結構,詳細文檔說明,下載Oracle的exp/imp,DUL,logminer,ASM工具的源代碼,學習高技術含量的內容。
ODBC的每個函數調用完畢都會返回一個SQLRETURN類型的返回碼,這個類型其實是短整數(short int)類型,是一個16位的整數。返回值一共有下面幾個值。
1. SQL_SUCCESS,表示函數執行成功。
2. SQL_SUCCESS_WITH_INFO,表示函數執行成功,但是返回了警告信息。比如連接數據庫時返回密碼即將過期信息。
3. SQL_STILL_EXECUTING,表示調用函數時,前一個SQL語句還在執行。
4. SQL_NEED_DATA,表示調用函數后,有動態數據需要提供。
5. SQL_NO_DATA,表示調用函數后,沒有數據返回。最典型的就是從結果集中Fetch數據時,取走最后一條數據后沒有其他數據了,返回SQL_NO_DATA。
6. SQL_ERROR,表示調用函數后,出現了錯誤。需要調用診斷函數獲取錯誤信息。
7. SQL_INVALID_HANDLE,表示調用函數時,傳入了無效的句柄。
當調用的函數返回SQL_SUCCESS_WITH_INFO或SQL_ERROR時,可以調用SQLGetDiagRec()函數來返回錯誤信息,下面看看函數的原型和參數。
SQLRETURN SQLGetDiagRec(
SQLSMALLINT HandleType,
SQLHANDLE Handle,
SQLSMALLINT RecNumber,
SQLCHAR * SQLState,
SQLINTEGER * NativeErrorPtr,
SQLCHAR * MessageText,
SQLSMALLINT BufferLength,
SQLSMALLINT * TextLengthPtr);
HandleType是一個輸入參數,是出錯函數傳入的句柄的類型。
Handle是一個輸入參數,是出錯函數傳入的句柄。
RecNumber是一個輸入參數,指示診斷記錄的編號。記錄從 1 開始編號。
SQLState是一個輸出參數,返回狀態碼,該緩沖區將返回一個五個字符的 SQLSTATE 代碼。
NativeErrorPtr是一個輸出參數,返回錯誤碼,該緩沖區將返回特定于數據源的本機錯誤代碼。比如數據源是一個使用Oracle驅動程序的配置項,那么返回的就是Oracle的出錯碼。
MessageText是一個輸出參數,指向返回診斷消息文本字符串的緩沖區的指針。用于存放出錯信息。
BufferLength是一個輸入參數,MessageText 緩沖區的長度(以字符為單位)。如果過小診斷函數會返回錯誤。
TextLengthPtr是一個輸出參數,返回信息文本的總字符數。
看一個例子,連接數據庫出錯時,怎樣處理錯誤。
SQLSMALLINT i; SQLRETURN rc; SQLINTEGER ecode; SQLSMALLINT alen; WCHAR msgtxt[8192]; WCHAR state[SQL_SQLSTATE_SIZE+1]; rc = SQLConnect(dbch, (SQLCHAR *)ds_name, SQL_NTS, (SQLCHAR *)usrname, SQL_NTS, (SQLCHAR *)passwd, SQL_NTS); if ((rc == SQL_ERROR) || (rc == SQL_SUCCESS_WITH_INFO)) { for (i=1; ; i++) { rc = SQLGetDiagRec(SQL_HANDLE_DBC, dbch, i, (SQLCHAR *)state, &ecode, (SQLCHAR *)msgtxt, (SQLSMALLINT)(sizeof(msgtxt) / sizeof(WCHAR)), (SQLSMALLINT *)&alen); if (rc == SQL_SUCCESS) { fprintf(stderr, "ERROR: [%s] [%d] - %s\n", (char *)state, ecode, (char *)msgtxt); } else if (rc == SQL_NO_DATA) break; else { fprintf(stderr, "get diagnostic record error.\n"); break; } } }
我們可以寫一個函數來處理調用函數返回的結果。代碼如下。
/* * hndl - 出錯函數輸入的句柄 * htype - 出錯函數輸入的句柄類型 * rc - 出錯函數的返回碼 */
SQLRETURN check_odbc_error(SQLHANDLE hndl, SQLSMALLINT htype, SQLRETURN rc){ SQLRETURN ret; SQLSMALLINT irec; SQLSMALLINT alen; SQLINTEGER ecode; WCHAR msgtxt[8192]; WCHAR state[SQL_SQLSTATE_SIZE+1]; switch (rc) { /* 函數返回成功,需要動態數據,沒有數據了,直接返回原始碼,不用處理錯誤 */ case SQL_SUCCESS: case SQL_NEED_DATA: case SQL_NO_DATA: return (rc); /* 無效句柄 */ case SQL_INVALID_HANDLE: fprintf(stderr, "Invalid handle!\n"): return (rc); /* 返回成功但有警告信息或者出錯,處理錯誤記錄 */ case SQL_SUCCESS_WITH_INFO: case SQL_ERROR: /* 從1開始取回每一條出錯記錄信息 */ for (irec=1; ; irec++) { ret = SQLGetDiagRec(htype, hndl, irec, (SQLCHAR *)state, &ecode, (SQLCHAR *)msgtxt, (SQLSMALLINT)(sizeof(msgtxt) / sizeof(WCHAR)), (SQLSMALLINT *)&alen); if (ret == SQL_NO_DATA) break; if (ret == SQL_SUCCESS) { fprintf(stderr,"[%s] %d - %s\n", (char *)state, ecode, (char *)msgtxt); } else { fprintf(stderr, "Get diagnostic message error!\n"); break; } } return (rc); } return (0); }
后面可以使用上面的函數來處理調用函數的返回碼,簡單實用,比如調用執行語句函數。
rc = SQLExecute(stmth);
check_odbc_error(stmth, SQL_HANDLE_STMT, rc);
如果你想看一些有關數據庫的高技術含量的源代碼和文檔,請訪問www.tomcoding.com網站。

浙公網安備 33010602011771號