2015-10-06 79 views
1

我想捕捉異常,使用try這occures在我的代碼/趕上這樣的:的try-catch不能捕獲的異常

try 
{ 
//my code 
} 
catch(std::exception &e) 
    { 
     std::wcout <<"An exception occured"<<" "<<e.what(); 
    } 

但這種結構捉不到風度在我的例外碼。我在這行收到Visual Studio的一個例外:

retcode = bcp_init(hdbc1,"information1", NULL,NULL, DB_IN); 

而不是從我的try/catch中。

在這裏你可以看到我的整個代碼:

#include <stdio.h> 
#include <string.h> 
#include <windows.h> 
#include <sql.h> 
#include <sqlext.h> 
#include<tchar.h> 
#include<iostream> 
#include<sqlncli.h> 
#include<exception> 
using namespace std; 

SQLHENV henv = SQL_NULL_HENV; 
HDBC hdbc1 = SQL_NULL_HDBC, hdbc2 = SQL_NULL_HDBC; 
SQLHSTMT hstmt2 = SQL_NULL_HSTMT; 

void Cleanup() { 
    if (hstmt2 != SQL_NULL_HSTMT) 
     SQLFreeHandle(SQL_HANDLE_STMT, hstmt2); 

    if (hdbc1 != SQL_NULL_HDBC) { 
     SQLDisconnect(hdbc1); 
     SQLFreeHandle(SQL_HANDLE_DBC, hdbc1); 
    } 

    if (hdbc2 != SQL_NULL_HDBC) { 
     SQLDisconnect(hdbc2); 
     SQLFreeHandle(SQL_HANDLE_DBC, hdbc2); 
    } 

    if (henv != SQL_NULL_HENV) 
     SQLFreeHandle(SQL_HANDLE_ENV, henv); 
} 

int main() { 
try 
{ 
    RETCODE retcode; 

    // BCP variables. 
    char *terminator = "\0"; 

    // bcp_done takes a different format return code because it returns number of rows bulk copied 
    // after the last bcp_batch call. 
    DBINT cRowsDone = 0; 

    // Set up separate return code for bcp_sendrow so it is not using the same retcode as SQLFetch. 
    RETCODE SendRet; 



    // Allocate the ODBC environment and save handle. 
    retcode = SQLAllocHandle (SQL_HANDLE_ENV, NULL, &henv); 
    if ((retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) { 
     printf("SQLAllocHandle(Env) Failed\n\n"); 
     Cleanup(); 
     return(9); 
    } 

    // Notify ODBC that this is an ODBC 3.0 app. 
    retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, SQL_IS_INTEGER); 
    if ((retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) { 
     printf("SQLSetEnvAttr(ODBC version) Failed\n\n"); 
     Cleanup(); 
     return(9);  
    } 

    // Allocate ODBC connection handle, set bulk copy mode, and connect. 
    retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc1); 
    if ((retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) { 
     printf("SQLAllocHandle(hdbc1) Failed\n\n"); 
     Cleanup(); 
     return(9); 
    } 

    retcode = SQLSetConnectAttr(hdbc1, SQL_COPT_SS_BCP, (void *)SQL_BCP_ON, SQL_IS_INTEGER); 
    if ((retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) { 
     printf("SQLSetConnectAttr(hdbc1) Failed\n\n"); 
     Cleanup(); 
     return(9); 
    } 

    // sample uses Integrated Security, create the SQL Server DSN using Windows NT authentication 
    SQLWCHAR dsn[30] = L"mssqltest"; //Name DNS 
    SQLWCHAR user[10] = L"di_test"; 
    SQLWCHAR pass[10] = L"di_test"; 
// SQLWCHAR tb[20]=L"information1"; 

    retcode = SQLConnectW(hdbc1, (SQLWCHAR *)dsn, SQL_NTS, (SQLWCHAR *) user, SQL_NTS, (SQLWCHAR *) pass, SQL_NTS); 
    if ((retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO)) { 
     printf("SQLConnect() Failed\n\n"); 
     Cleanup(); 
     return(9); 
    } 
    // TRYODBC(hdbc1, SQL_HANDLE_DBC, retcode); 
    // Initialize the bulk copy. 



    retcode = bcp_init(hdbc1,"information1", NULL,NULL, DB_IN); 
    /* TRYODBC(hdbc1, SQL_HANDLE_DBC, retcode);*/ 
    if ((retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO)) { 
     printf("bcp_init(hdbc1) Failed\n\n"); 
     Cleanup(); 
     return(9); 
    } 

    //Define our array 
    DBINT custIDs[] ={1,2,3,4}; 

    // Bind the program variables for the bulk copy. 
    if(bcp_bind(hdbc1, (BYTE *)&custIDs, 0, sizeof(DBINT), NULL,0, SQLINT4, 2)==FAIL) 
    { 
     retcode=-1; 
    } 
    if ((retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) { 
     printf("bcp_bind(hdbc1) Failed\n\n"); 
     Cleanup(); 
     return(9); 
    } 

    // Could normally use strlen to calculate the bcp_bind cbTerm parameter, but this terminator 
    // is a null byte (\0), which gives strlen a value of 0. Explicitly give cbTerm a value of 1. 
    if(bcp_bind(hdbc1,(LPCBYTE) custIDs, 2, SQL_VARLEN_DATA, NULL,0, SQL_C_NUMERIC, 3)==FAIL) 
    { 
     retcode=-1; 
    } 
    if ((retcode != SUCCEED)) { 
     printf("bcp_bind(hdbc1) Failed\n\n"); 
     Cleanup(); 
     return(9); 
    } 


    if ((SendRet = bcp_sendrow(hdbc1)) != SUCCEED) { 
     printf("bcp_sendrow(hdbc1) Failed\n\n"); 
     Cleanup(); 
     return(9); 
     } 

    cRowsDone = bcp_done(hdbc1); 
    if ((cRowsDone == -1)) { 
     printf("bcp_done(hdbc1) Failed\n\n"); 
     Cleanup(); 
     return(9); 
    } 



    printf("Number of rows bulk copied after last bcp_batch call = %d.\n", cRowsDone); 

    // Cleanup. 
    SQLFreeHandle(SQL_HANDLE_STMT, hstmt2); 
    SQLDisconnect(hdbc1); 
    SQLFreeHandle(SQL_HANDLE_DBC, hdbc1); 
    SQLDisconnect(hdbc2); 
    SQLFreeHandle(SQL_HANDLE_DBC, hdbc2); 
    SQLFreeHandle(SQL_HANDLE_ENV, henv); 
    } 
    catch(std::exception &e) 
    { 
     std::wcout <<"An exception occured"<<" "<<e.what(); 
    } 
} 
+0

您只能捕獲C++異常。你的代碼中使用的任何函數是否會拋出C++異常? – ForEveR

+0

你的模型是不正確的。請更清楚地描述問題,簡單的事實。沒有猜測。 –

+0

我已更新我的帖子。希望現在有更多幫助。謝謝 – Kaja

回答

6

您沒有看到C++異常。這就是Microsoft所稱的SEH異常,實際上是程序崩潰。你可以捕獲這些(在MSDN上搜索__try和__except),但通常這就像Java NullPointerException - 這是一個編程錯誤,並且沒有錯誤處理可以解決這個問題。

此外,如果設置爲「中斷所有異常」,Visual Studio將在發生異常時斷開,該異常也將在try/catch中處理。如果你只是繼續執行,它會去相應的捕獲&被處理。如果發生這種情況,請關閉「中斷所有例外」。無論如何,它會停止在未處理的。

+0

不知道微軟的SEH例外,很好解釋! +1 –

+0

Thynk你爲你的好解釋。我通常會如何解決這個問題?你有什麼想法或提示? – Kaja

+0

看看Visual Studio說的例外是什麼。很可能這是「非法訪問」。這意味着有人收到一個指向內存的指針,該指針無效 - 指針可能已損壞,或者是空指針。因此,考慮到你在哪條線路上崩潰的跡象,你是否允許在這兩個地方傳遞空指針? – dascandy

4

C++是不是Java。 通用基類異常不存在,因此std::exception只是標準庫引發的所有異常的基類。

如果你想捕獲任何異常(而不是任何可能發生的奇怪錯誤),你可以使用catch(...)

SingerOfTheFall的評論所示,您可以使用C++ 11 std::current_exception來檢查異常對象。

+0

謝謝,但我怎樣才能看到異常。你能告訴我一個非常簡單的例子嗎? – Kaja

+1

@Kaja,http://en.cppreference.com/w/cpp/error/current_exception – SingerOfTheFall

+1

「看到」異常的唯一方法是在catch處理程序中指定它的類型(或基類) - 這意味着你需要事先知道例外的類型以便專門捕捉它。如果你不知道例外的類型,那麼你運氣不好。閱讀代碼調用函數的文檔,找出它們可能拋出的異常。 – Peter