處理應用程式中的錯誤和訊息
由 SQL Server Database Engine 或 RAISERROR 陳述式所引發的錯誤並非結果集的一部份。透過錯誤處理機制傳回給應用程式的錯誤,將與結果集分開處理。
每個資料庫應用程式發展介面 (API) 均有其傳回錯誤和訊息之函數、介面、方法、物件或結構的集合。通常每種 API 函數或方法都會傳回指出作業成功的狀態程式碼。如果狀態為成功以外的其他狀態,應用程式會呼叫錯誤函數、方法或物件來擷取錯誤資訊。
Database Engine 可以使用下列兩種方法的其中之一將資訊傳回給呼叫者:
錯誤
來自 sys.messages 的錯誤,具有 11 或更高的嚴重性。
任何一個 RAISERROR 陳述式,具有 11 或更高的嚴重性。
訊息
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 Server Native Client ODBC 驅動程式。ODBC 模型中的錯誤具有以下屬性:
SQLSTATE
SQLSTATE 是一個由五個字元所構成的錯誤代碼,最初定義於 ODBC 規格中。SQLSTATE 代碼在所有的 ODBC 驅動程式中是很常見的,它提供應用程式針對不同資料庫傳回各種不同的錯誤碼,編寫基本錯誤處理且無需測試的方法。ODBC SQLSTATE 與 Database Engine 錯誤訊息的狀態屬性毫不相關。
ODBC 2.x 會傳回一組 SQLSTATE 程式碼,而 ODBC 3.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 應用程式中錯誤訊息的詳細資訊,請參閱<處理錯誤與訊息>。
ADO 錯誤處理
ADO 以 Errors 物件和 Errors 集合傳回標準錯誤資訊,例如 SQLSTATE、自發性錯誤號碼和錯誤訊息字串。此作法與其對應的 ODBC 相同。ADO 並不支援任何提供者專用的錯誤介面,所以 Database Engine 的專用錯誤資訊 (例如嚴重性或狀態) 無法用於 ADO 應用程式。
如需有關擷取 ADO 應用程式之錯誤訊息的詳細資訊,請參閱<處理錯誤與訊息>。
OLE DB 錯誤處理
OLE DB 使用 IErrorInfo 介面傳回標準的錯誤資訊,例如 SQLSTATE、自發性錯誤號碼與錯誤字串。此作法與其對應的 ODBC 相同。SQL Server 的 OLE DB 提供者會定義 ISQLServerErrorInfo 介面,以傳回 Database Engine 的專用資訊,例如嚴重性、狀態、程序名稱與行號。
如需有關擷取 OLE DB 應用程式中錯誤訊息的詳細資訊,請參閱<錯誤>。
SqlClient 錯誤處理
SqlClient Managed 提供者會在 SQL Server Database Engine 引發未處理的錯誤時發生 SqlException 例外狀況。透過 SqlException 類別,應用程式可以擷取伺服器端所產生的錯誤,包括錯誤號碼、錯誤訊息、錯誤嚴重性以及其他的例外狀況的內容資訊。
為了處理 SQL Server Database Engine 所傳送之參考用訊息的警告,應用程式可以建立 SqlInfoMessageEventHandler 委託以接聽 SqlConnection 類別的 InfoMessage 事件。與例外狀況類似的是,諸如嚴重性和狀態等訊息內容資訊都將以引數傳遞至回呼。