void _iodbcdm_freesqlerrlist (HERR herrlist) { HERR list = herrlist; while (list != SQL_NULL_HERR) { list = _iodbcdm_popsqlerr (list); } }
RETCODE SQL_API SQLError ( HENV henv, HDBC hdbc, HSTMT hstmt, UCHAR FAR * szSqlstate, SDWORD FAR * pfNativeError, UCHAR FAR * szErrorMsg, SWORD cbErrorMsgMax, SWORD FAR * pcbErrorMsg) { GENV_t FAR *genv = (GENV_t FAR *) henv; DBC_t FAR *pdbc = (DBC_t FAR *) hdbc; STMT_t FAR *pstmt = (STMT_t FAR *) hstmt; HDBC thdbc; HENV dhenv = SQL_NULL_HENV; HDBC dhdbc = SQL_NULL_HDBC; HSTMT dhstmt = SQL_NULL_HSTMT; HERR herr = SQL_NULL_HERR; HPROC hproc = SQL_NULL_HPROC; char FAR *errmsg = NULL; char FAR *ststr = NULL; int handle = 0; RETCODE retcode = SQL_SUCCESS; if (hstmt != SQL_NULL_HSTMT) /* retrive stmt err */ { herr = pstmt->herr; thdbc = pstmt->hdbc; if (thdbc == SQL_NULL_HDBC) { return SQL_INVALID_HANDLE; } hproc = _iodbcdm_getproc (thdbc, en_Error); dhstmt = pstmt->dhstmt; handle = 3; } else if (hdbc != SQL_NULL_HDBC) /* retrive dbc err */ { herr = pdbc->herr; thdbc = hdbc; if (thdbc == SQL_NULL_HDBC) { return SQL_INVALID_HANDLE; } hproc = _iodbcdm_getproc (thdbc, en_Error); dhdbc = pdbc->dhdbc; handle = 2; if (herr == SQL_NULL_HERR && pdbc->henv == SQL_NULL_HENV) { return SQL_NO_DATA_FOUND; } } else if (henv != SQL_NULL_HENV) /* retrive env err */ { herr = genv->herr; /* Drivers shouldn't push error message * on envoriment handle */ if (herr == SQL_NULL_HERR) { return SQL_NO_DATA_FOUND; } handle = 1; } else { return SQL_INVALID_HANDLE; } if (szErrorMsg != NULL) { if (cbErrorMsgMax < 0 || cbErrorMsgMax > SQL_MAX_MESSAGE_LENGTH - 1) { return SQL_ERROR; /* SQLError() doesn't post error for itself */ } } if (herr == SQL_NULL_HERR) /* no err on drv mng */ { /* call driver */ if (hproc == SQL_NULL_HPROC) { PUSHSQLERR (herr, en_IM001); return SQL_ERROR; } CALL_DRIVER (thdbc, retcode, hproc, en_Error, (dhenv, dhdbc, dhstmt, szSqlstate, pfNativeError, szErrorMsg, cbErrorMsgMax, pcbErrorMsg)) return retcode; } if (szSqlstate != NULL) { int len; /* get sql state string */ ststr = (char FAR *) _iodbcdm_getsqlstate (herr, (void FAR *) sqlerrmsg_tab); if (ststr == NULL) { len = 0; } else { len = (int) STRLEN (ststr); } STRNCPY (szSqlstate, ststr, len); szSqlstate[len] = 0; /* buffer size of szSqlstate is not checked. Applications * suppose provide enough ( not less than 6 bytes ) buffer * or NULL for it. */ } if (pfNativeError != NULL) { /* native error code is specific to data source */ *pfNativeError = (SDWORD) 0L; } if (szErrorMsg == NULL || cbErrorMsgMax == 0) { if (pcbErrorMsg != NULL) { *pcbErrorMsg = (SWORD) 0; } } else { int len; char msgbuf[256] = {'\0'}; /* get sql state message */ errmsg = _iodbcdm_getsqlerrmsg (herr, (void FAR *) sqlerrmsg_tab); if (errmsg == NULL) { errmsg = (char FAR *) ""; } sprintf (msgbuf, "%s%s", sqlerrhd, errmsg); len = STRLEN (msgbuf); if (len < cbErrorMsgMax - 1) { retcode = SQL_SUCCESS; } else { len = cbErrorMsgMax - 1; retcode = SQL_SUCCESS_WITH_INFO; /* and not posts error for itself */ } STRNCPY ((char *) szErrorMsg, msgbuf, len); szErrorMsg[len] = 0; if (pcbErrorMsg != NULL) { *pcbErrorMsg = (SWORD) len; } } switch (handle) /* free this err */ { case 1: genv->herr = _iodbcdm_popsqlerr (genv->herr); break; case 2: pdbc->herr = _iodbcdm_popsqlerr (pdbc->herr); break; case 3: pstmt->herr = _iodbcdm_popsqlerr (pstmt->herr); break; default: break; } return retcode; }
SQLRETURN SQL_API _iodbcdm_sqlerror ( SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt, SQLPOINTER szSqlstate, SQLINTEGER * pfNativeError, SQLPOINTER szErrorMsg, SQLSMALLINT cbErrorMsgMax, SQLSMALLINT * pcbErrorMsg, int bDelete, SQLCHAR waMode) { GENV (genv, henv); CONN (pdbc, hdbc); STMT (pstmt, hstmt); HDBC thdbc = SQL_NULL_HDBC; HENV dhenv = SQL_NULL_HENV; HDBC dhdbc = SQL_NULL_HDBC; HSTMT dhstmt = SQL_NULL_HSTMT; HERR herr = SQL_NULL_HERR; HPROC hproc2 = SQL_NULL_HPROC; HPROC hproc3 = SQL_NULL_HPROC; #if (ODBCVER >= 0x0300) SQLINTEGER handleType = 0; SQLHANDLE handle3; SQLHANDLE dhandle3 = 0; SQLSMALLINT *perr_rec = NULL; #endif SWORD unicode_driver = 0; SQLUINTEGER dodbc_ver = SQL_OV_ODBC2; SQLUINTEGER odbc_ver = SQL_OV_ODBC2; wchar_t _sqlState[6] = {L"\0"}; void *SqlstateOut = szSqlstate; void *_ErrorMsg = NULL; void *errorMsgOut = szErrorMsg; void *errmsg = NULL; void *ststr = NULL; int handle = 0; SQLRETURN retcode = SQL_SUCCESS; if (IS_VALID_HSTMT (hstmt)) /* retrieve stmt err */ { herr = pstmt->herr; thdbc = pstmt->hdbc; if (thdbc == SQL_NULL_HDBC) { return SQL_INVALID_HANDLE; } #if (ODBCVER >= 0x0300) handleType = SQL_HANDLE_STMT; handle3 = hstmt; dhandle3 = pstmt->dhstmt; perr_rec = &((STMT_t *)pstmt)->err_rec; #endif dhstmt = pstmt->dhstmt; handle = 3; } else if (IS_VALID_HDBC (hdbc)) /* retrieve dbc err */ { herr = pdbc->herr; thdbc = pdbc; if (thdbc == SQL_NULL_HDBC) { return SQL_INVALID_HANDLE; } #if (ODBCVER >= 0x0300) handleType = SQL_HANDLE_DBC; handle3 = hdbc; dhandle3 = pdbc->dhdbc; perr_rec = &((DBC_t *)pdbc)->err_rec; #endif dhdbc = pdbc->dhdbc; handle = 2; if (herr == SQL_NULL_HERR && pdbc->henv == SQL_NULL_HENV) { return SQL_NO_DATA_FOUND; } } else if (IS_VALID_HENV (henv)) /* retrieve env err */ { herr = genv->herr; /* Drivers shouldn't push error message * on environment handle */ if (herr == SQL_NULL_HERR) { return SQL_NO_DATA_FOUND; } handle = 1; } else { return SQL_INVALID_HANDLE; } if (szErrorMsg != NULL) { if (cbErrorMsgMax < 0) { return SQL_ERROR; /* SQLError() doesn't post error for itself */ } } if (herr == SQL_NULL_HERR) /* no err on drv mng */ { if (thdbc && ((DBC_t *)thdbc)->genv) odbc_ver = ((GENV_t *) ((DBC_t *)thdbc)->genv)->odbc_ver; if (thdbc && ((DBC_t *)thdbc)->henv) { unicode_driver = ((ENV_t *) ((DBC_t *)thdbc)->henv)->unicode_driver; dodbc_ver = ((ENV_t *) ((DBC_t *)thdbc)->henv)->dodbc_ver; } /* call driver */ if ((unicode_driver && waMode != 'W') || (!unicode_driver && waMode == 'W')) { if (waMode != 'W') { /* ansi=>unicode*/ if ((_ErrorMsg = malloc(cbErrorMsgMax * sizeof(wchar_t) + 1)) == NULL) return SQL_ERROR; } else { /* unicode=>ansi*/ if ((_ErrorMsg = malloc(cbErrorMsgMax + 1)) == NULL) return SQL_ERROR; } errorMsgOut = _ErrorMsg; SqlstateOut = _sqlState; } /* call driver */ if (unicode_driver) { /* SQL_XXX_W */ hproc2 = _iodbcdm_getproc (thdbc, en_ErrorW); #if (ODBCVER >= 0x300) hproc3 = _iodbcdm_getproc (thdbc, en_GetDiagRecW); #endif } else { /* SQL_XXX */ /* SQL_XXX_A */ hproc2 = _iodbcdm_getproc (thdbc, en_Error); if (hproc2 == SQL_NULL_HPROC) hproc2 = _iodbcdm_getproc (thdbc, en_ErrorA); #if (ODBCVER >= 0x300) hproc3 = _iodbcdm_getproc (thdbc, en_GetDiagRec); if (hproc3 == SQL_NULL_HPROC) hproc3 = _iodbcdm_getproc (thdbc, en_GetDiagRecA); #endif } if (odbc_ver == SQL_OV_ODBC2 && ( dodbc_ver == SQL_OV_ODBC2 || (dodbc_ver == SQL_OV_ODBC3 && hproc2 != SQL_NULL_HPROC))) hproc3 = SQL_NULL_HPROC; #if (ODBCVER >= 0x300) if (hproc3 != SQL_NULL_HPROC) { (*perr_rec) = (*perr_rec) + 1; CALL_DRIVER (thdbc, NULL, retcode, hproc3, ( handleType, dhandle3, (*perr_rec), SqlstateOut, pfNativeError, errorMsgOut, cbErrorMsgMax, pcbErrorMsg)); } else #endif { if (hproc2 == SQL_NULL_HPROC) { MEM_FREE(_ErrorMsg); return SQL_NO_DATA_FOUND; } CALL_DRIVER (thdbc, NULL, retcode, hproc2, ( dhenv, dhdbc, dhstmt, SqlstateOut, pfNativeError, errorMsgOut, cbErrorMsgMax, pcbErrorMsg)); } if (szErrorMsg && SQL_SUCCEEDED (retcode) && ((unicode_driver && waMode != 'W') || (!unicode_driver && waMode == 'W'))) { if (waMode != 'W') { /* ansi<=unicode*/ dm_StrCopyOut2_W2A ((SQLWCHAR *)errorMsgOut, (SQLCHAR *)szErrorMsg, cbErrorMsgMax, NULL); dm_StrCopyOut2_W2A ((SQLWCHAR *)SqlstateOut, (SQLCHAR *)szSqlstate, 6, NULL); } else { /* unicode<=ansi*/ dm_StrCopyOut2_A2W ((SQLCHAR *)errorMsgOut, (SQLWCHAR *)szErrorMsg, cbErrorMsgMax, NULL); dm_StrCopyOut2_A2W ((SQLCHAR *)SqlstateOut, (SQLWCHAR *)szSqlstate, 6, NULL); } } MEM_FREE(_ErrorMsg); return retcode; } if (szSqlstate != NULL) { int len; /* get sql state string */ ststr = (char *) _iodbcdm_getsqlstate (herr, (void *) sqlerrmsg_tab); if (ststr == NULL) { len = 0; } else { len = (int) STRLEN (ststr); } /* buffer size of szSqlstate is not checked. Applications * suppose provide enough ( not less than 6 bytes ) buffer * or NULL for it. */ if (waMode != 'W') { STRNCPY (szSqlstate, ststr, len); ((char*)szSqlstate)[len] = 0; } else { dm_StrCopyOut2_A2W ((SQLCHAR *)ststr, (SQLWCHAR *)szSqlstate, 6, NULL); ((wchar_t*)szSqlstate)[len] = 0; } } if (pfNativeError != NULL) { /* native error code is specific to data source */ *pfNativeError = (SDWORD) 0L; } if (szErrorMsg == NULL || cbErrorMsgMax == 0) { if (pcbErrorMsg != NULL) { *pcbErrorMsg = (SWORD) 0; } } else { int len; char msgbuf[256] = {'\0'}; /* get sql state message */ errmsg = _iodbcdm_getsqlerrmsg (herr, (void *) sqlerrmsg_tab); if (errmsg == NULL) { errmsg = (char *) ""; } #if defined(HAVE_SNPRINTF) snprintf (msgbuf, sizeof(msgbuf), "%s%s", sqlerrhd, (char*)errmsg); #else sprintf (msgbuf, "%s%s", sqlerrhd, (char*)errmsg); #endif len = STRLEN (msgbuf); if (len < cbErrorMsgMax - 1) { retcode = SQL_SUCCESS; } else { len = cbErrorMsgMax - 1; retcode = SQL_SUCCESS_WITH_INFO; /* and not posts error for itself */ } if (waMode != 'W') { STRNCPY ((char *) szErrorMsg, msgbuf, len); ((char*)szErrorMsg)[len] = 0; if (pcbErrorMsg != NULL) *pcbErrorMsg = (SWORD) len; } else { dm_StrCopyOut2_A2W ((SQLCHAR *) msgbuf, (SQLWCHAR *) szErrorMsg, cbErrorMsgMax, pcbErrorMsg); } } if (bDelete) switch (handle) /* free this err */ { case 1: genv->herr = _iodbcdm_popsqlerr (genv->herr); break; case 2: pdbc->herr = _iodbcdm_popsqlerr (pdbc->herr); break; case 3: pstmt->herr = _iodbcdm_popsqlerr (pstmt->herr); break; default: break; } return retcode; }