SqlServer try catch 捕獲不到的一些錯誤及解決方法


  • IF (OBJECT_ID('AA','U') IS NOT NULL)  
  • DROP TABLE AA  
  • CREATE TABLE AA(ID INT)  
  •   
  • SELECT * FROM AA  
  •   
  • --注:數據庫當前只存在表AA,無表#BB和表BB  
  •   
  • -----------------------------------------------------  
  • -----------------------------------------------------  
  •   
  • --  【案例1】  
  • BEGIN TRAN   
  • BEGIN TRY  
  •     INSERT INTO AA SELECT 1     --A處  
  •     INSERT INTO #BB SELECT 1    --B處  
  •     COMMIT TRAN;  
  • END TRY  
  • BEGIN CATCH  
  •     SELECT ERROR_MESSAGE() AS ErrorMessage  
  •     ,ERROR_SEVERITY() AS ErrorSeverity  
  •     ,ERROR_STATE() AS ErrorState  
  •     ROLLBACK TRAN;  
  • END CATCH  
  •   
  • /*運行結果:  
  •   
  • (1 行受影響)  
  • 消息 208,級別 16,狀態 0,第 4 行  
  • 對象名 '#BB' 無效。  
  •   
  •   
  • 說明:A處已經執行;B處中斷操作,下面語句未執行  
  •     查詢表AA已經有數據,此時可手動繼續操作提交或回滾  
  • */  
  •   
  • -----------------------------------------------------  
  • -----------------------------------------------------  
  • --  【案例2】  
  • BEGIN TRAN   
  • BEGIN TRY  
  •     INSERT INTO AA SELECT 1     --A處  
  •     INSERT INTO BB SELECT 1     --B處  
  •     COMMIT TRAN;  
  • END TRY  
  • BEGIN CATCH  
  •     SELECT ERROR_MESSAGE() AS ErrorMessage  
  •     ,ERROR_SEVERITY() AS ErrorSeverity  
  •     ,ERROR_STATE() AS ErrorState  
  •     ROLLBACK TRAN;  
  • END CATCH  
  •   
  • /*運行結果:  
  • 注意:【案例1】使用臨時表#BB,【案例2】使用表BB  
  •   
  •   
  • 選中代碼執行兩次,結果不一樣!  
  •   
  • 第一次執行結果(不捕獲異常),同【案例1】:  
  •   
  • (1 行受影響)  
  • 消息 208,級別 16,狀態 0,第 4 行  
  • 對象名 '#BB' 無效。  
  •   
  •   
  • 第二次執行結果(捕獲異常):  
  • ErrorMessage    ErrorSeverity   ErrorState  
  • 對象名 'BB' 無效。    16          1  
  •   
  •   
  • */  
  • -----------------------------------------------------  
  • -----------------------------------------------------  
  •   
  • --  【案例3】  
  • BEGIN TRAN   
  • BEGIN TRY  
  •     INSERT INTO AA SELECT 1     --A處  
  •     INSERT INTO AA SELECT 'kk'  --B處  
  •     COMMIT TRAN;  
  • END TRY  
  • BEGIN CATCH  
  •     SELECT ERROR_MESSAGE() AS ErrorMessage  
  •     ,ERROR_SEVERITY() AS ErrorSeverity  
  •     ,ERROR_STATE() AS ErrorState  
  •     ROLLBACK TRAN;  
  • END CATCH  
  •   
  • /*運行結果(正常捕獲異常):  
  •   
  • ErrorMessage                                ErrorSeverity   ErrorState  
  • 在將 varchar 值 'kk' 轉換成數據類型 int 時失敗。  16      1  
  • */  
  •   
  •   
  • -----------------------------------------------------  
  • -----------------------------------------------------  
  •   
  • --  【案例4:解決方案】  
  •   
  • BEGIN TRAN   
  • BEGIN TRY  
  •     INSERT INTO AA SELECT 1         --A處  
  •     EXEC('INSERT INTO #BB SELECT 1')--B處  
  •     COMMIT TRAN;  
  • END TRY  
  • BEGIN CATCH  
  •     SELECT ERROR_MESSAGE() AS ErrorMessage  
  •     ,ERROR_SEVERITY() AS ErrorSeverity  
  •     ,ERROR_STATE() AS ErrorState  
  •     ROLLBACK TRAN;  
  • END CATCH  
  •   
  • /*正常捕獲異常!  
  •   
  • 不報之前錯誤:對象名 '#BB' 無效。  
  •   
  • 但要求格式為:EXEC(@sql)  
  • */  
  •   
  • -----------------------------------------------------  
  • -----------------------------------------------------  
  •   
  • --  【案例5:解決方案】  
  • SET XACT_ABORT ON  
  • BEGIN TRAN   
  • BEGIN TRY  
  •     INSERT INTO AA SELECT 1     --A處  
  •     INSERT INTO #BB SELECT 1    --B處  
  •     COMMIT TRAN;  
  • END TRY  
  • BEGIN CATCH  
  •     SELECT ERROR_MESSAGE() AS ErrorMessage  
  •     ,ERROR_SEVERITY() AS ErrorSeverity  
  •     ,ERROR_STATE() AS ErrorState  
  •     ROLLBACK TRAN;  
  • END CATCH  
  • SET XACT_ABORT OFF  
  •   
  •   
  • /*運行結果:  
  •   
  •   
  • (1 行受影響)  
  • 消息 208,級別 16,狀態 0,第 5 行  
  • 對象名 '#BB' 無效。  
  •   
  • 報錯,但是事務會自動回滾.  
  • 系統默認: SET XACT_ABORT OFF  
  • 當 SET XACT_ABORT 為 ON 時,如果執行 Transact-SQL 語句產生運行時錯誤,則整個事務將終止並回滾。  
  • */  
  •   
  •   
  • --查看 XACT_ABORT 是否打開  
  • SELECT (CASE WHEN (16384 & @@OPTIONS) = 16384 THEN 'ON' ELSE 'OFF' END) AS XACT_ABORT;  
  •   
  •   
  • /*  
  •   
  • 1. 輕微錯誤(嚴重性級別為0-10):默認情況下不會給客戶程序發送錯誤消息,繼續工作。也就是說它無法被CATCH到  
  •   
  • 2. 中等錯誤(嚴重性級別為11-19):能夠被CATCH到(不管是在T-SQL里面還是在客戶程序里面)  
  •   
  • 3. 嚴重錯誤(嚴重性級別為20-25):SQL Server將強制把連接關掉。很顯然這也不可能被CATCH到  
  •   
  •   
  • 【重點提示!!】  
  •   
  • 由於業務的復雜或者系統性能問題,致使數據庫sql語句執行較久。  
  •   
  • 導致客戶端網頁已經連接超時(如設置為30秒)  
  •   
  • 此時數據庫批處理語句未執行完成,客戶session斷開,相當於中斷操作,類似【案例1】的中斷。  
  •   
  • 事務是沒有提交或回滾的,資源仍在占用,導致發生堵塞或死鎖!~  
  •   
  •   
  •   
  • 【解決方法】:  
  •   
  • 在批處理語句前加上 SET XACT_ABORT ON  
  • 當客戶端中斷的時候,未執行完成則回滾操作,及時釋放資源。  
  •   
  • */ 

  • 免責聲明!

    本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



     
    粵ICP備18138465號   © 2018-2025 CODEPRJ.COM