處理應用程式中的錯誤和訊息

由 SQL Server Database Engine 或 RAISERROR 陳述式所引發的錯誤並非結果集的一部份。透過錯誤處理機制傳回給應用程式的錯誤,將與結果集分開處理。

每個資料庫應用程式發展介面 (API) 均有其傳回錯誤和訊息之函數、介面、方法、物件或結構的集合。通常每種 API 函數或方法都會傳回指出作業成功的狀態程式碼。如果狀態為成功以外的其他狀態,應用程式會呼叫錯誤函數、方法或物件來擷取錯誤資訊。

Database Engine 可以使用下列兩種方法的其中之一將資訊傳回給呼叫者:

  1. 錯誤
    • 來自 sys.messages 的錯誤,具有 11 或更高的嚴重性。
    • 任何一個 RAISERROR 陳述式,具有 11 或更高的嚴重性。
  2. 訊息
    • PRINT 陳述式的輸出結果。
    • 多個 DBCC 陳述式的輸出結果。
    • 來自 sys.messages 的錯誤,具有 10 或更低的嚴重性。
    • 任何一個 RAISERROR 陳述式,具有 10 或更低的嚴重性。

使用 API (例如 ActiveX Data Object (ADO) 與 OLE DB) 的應用程式通常無法分辨錯誤和訊息。在「開放式資料庫連接」(Open Database Connectivity,ODBC) 應用程式中,訊息會產生 SQL_SUCCESS_WITH_INFO 函數傳回碼,而錯誤通常會產生 SQL_ERROR 傳回碼。在 DB-Library 中的差異最為明顯,其中錯誤會傳回至應用程式錯誤處理常式函數,而訊息則會傳回至應用程式訊息處理常式函數。同樣的,當使用 SqlClient 提供者時,錯誤會造成 SqlException 例外狀況的發生;訊息不會修改控制流程,而且透過為 InfoMessage 事件處理常式註冊回呼,應用程式就可攔截訊息。

其他的元件也可能引發錯誤:

  • SQL Server 提供者的 OLE DB 以及 SQL Server ODBC 驅動程式會引發自己的錯誤。這些錯誤的格式與 API 規格中定義的格式一致。
  • 網路程式庫提出其專屬的錯誤。
  • 「擴充預存程序」(Extended Stored Procedure) API 以其專屬的格式引發錯誤。
  • SQL Server 的精靈、應用程式以及公用程式 (例如,SQL Server Management Studio 以及 sqlcmd 公用程式) 有可能引發自己的錯誤。

這些元件的錯誤將傳回給與 Database Engine 的錯誤使用相同基本機制的呼叫應用程式。應用程式可以處理這些與 Database Engine 錯誤使用相同錯誤處理邏輯的錯誤。因為這些錯誤是在 Database Engine 之外引發,所以無法在 Transact-SQL TRY...CATCH 建構中處理它們。如需詳細資訊,請參閱<TRY...CATCH (Transact-SQL)>。

ODBC 錯誤處理

ODBC 規格提供了一種錯誤模型,可做為一般資料庫 API (例如,ADO 與 OLE DB) 或建立在 ODBC (RDO、「資料存取物件」(Data Access Object ,DAO) 與 Microsoft Foundation Classes (MFC) 資料庫類別) 上之 API 的錯誤模型基礎。這也適用於 SQL Native Client ODBC 驅動程式。ODBC 模型中的錯誤具有以下屬性:

  • SQLSTATE
    SQLSTATE 是一個由五個字元所構成的錯誤代碼,最初定義於 ODBC 規格中。SQLSTATE 代碼在所有的 ODBC 驅動程式中是很常見的,它提供應用程式針對不同資料庫傳回各種不同的錯誤碼,編寫基本錯誤處理且無需測試的方法。ODBC SQLSTATE 與 Database Engine 錯誤訊息的狀態屬性毫不相關。
    ODBC 2.x 傳回一組 SQLSTATE 程式碼,ODBC 3.x 傳回一組與 X/Open Data Management 結合的 SQLSTATE 程式碼:結構化查詢語言 (SQL) 2 標準版。因為所有的 ODBC 驅動程式傳回同樣 SQLSTATE 程式碼組,使得其錯誤處理常式以 SQLSTATE 程式碼為基礎的應用程式更具可攜性。
  • 自發性錯誤號碼
    自發性錯誤號碼是基礎資料庫的錯誤號碼。ODBC 應用程式所收到的 Database Engine 錯誤號碼將為自發性錯誤號碼。
  • 錯誤訊息字串
    錯誤訊息以錯誤訊息字串參數傳回。

ODBC 函數傳回 SQL_SUCCESS 以外的狀態時,應用程式會呼叫 SQLGetDiagRec 以取得錯誤資訊。例如,如果 ODBC 應用程式取得語法錯誤 (SQL Server 錯誤號碼 170),SQLGetDiagRec 會傳回:

szSqlState = 42000, pfNative = 170
szErrorMsg =
'[Microsoft][ODBC SQL Server Driver][SQL Server]
                                     Line 1: Incorrect syntax near *'

ODBC SQLGetDiagField 函數可讓 ODBC 驅動程式在驅動程式傳回的診斷記錄中,指定驅動程式的專用診斷欄位。SQL Server ODBC 驅動程式可以指定驅動程式專用欄位,以容納 Database Engine 的錯誤資訊 (例如,Database Engine 的嚴重性和狀態代碼)。

如需有關擷取 ODBC 應用程式中錯誤訊息的詳細資訊,請參閱<Handling Errors and Messages>。

ADO 錯誤處理

ADO 以 Errors 物件和 Errors 集合傳回標準錯誤資訊,例如 SQLSTATE、自發性錯誤號碼和錯誤訊息字串。此作法與其對應的 ODBC 相同。ADO 並不支援任何提供者專用的錯誤介面,所以 Database Engine 的專用錯誤資訊 (例如嚴重性或狀態) 無法用於 ADO 應用程式。

如需有關擷取 ADO 應用程式之錯誤訊息的詳細資訊,請參閱<Handling Errors and Messages>。

OLE DB 錯誤處理

OLE DB 使用 IErrorInfo 介面傳回標準的錯誤資訊,例如 SQLSTATE、自發性錯誤號碼與錯誤字串。此作法與其對應的 ODBC 相同。SQL Server 的 OLE DB 提供者會定義 ISQLServerErrorInfo 介面,以傳回 Database Engine 的專用資訊,例如嚴重性、狀態、程序名稱與行號。

如需有關擷取 OLE DB 應用程式中錯誤訊息的詳細資訊,請參閱<Errors>。

SqlClient 錯誤處理

SqlClient Managed 提供者會在 SQL Server Database Engine 引發未處理的錯誤時發生 SqlException 例外狀況。透過 SqlException 類別,應用程式可以擷取伺服器端所產生的錯誤,包括錯誤號碼、錯誤訊息、錯誤嚴重性以及其他的例外狀況的內容資訊。

為了處理 SQL Server Database Engine 所傳送之參考用訊息的警告,應用程式可以建立 SqlInfoMessageEventHandler 委託以接聽 SqlConnection 類別的 InfoMessage 事件。與例外狀況類似的是,諸如嚴重性和狀態等訊息內容資訊都將以引數傳遞至回呼。

請參閱

概念

使用 PRINT
使用 @@ERROR
使用 RAISERROR
在 Transact-SQL 中使用 TRY...CATCH

其他資源

處理 Database Engine 錯誤
sys.messages (Transact-SQL)
RAISERROR (Transact-SQL)
TRY...CATCH (Transact-SQL)

說明及資訊

取得 SQL Server 2005 協助