国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > 綜合 > 正文

曲演雜壇--使用TRY CATCH應(yīng)該注意的一個(gè)小細(xì)節(jié)

2024-07-21 02:49:18
字體:
供稿:網(wǎng)友
曲演雜壇--使用TRY CATCH應(yīng)該注意的一個(gè)小細(xì)節(jié)

群里一個(gè)朋友遇到一個(gè)TRY CATCH的小問題,測試后發(fā)現(xiàn)是自己從來沒有考慮的情況,寫篇blog加深下印象

--=========================================================

在MSDN上對TRY CATCH有如下描述:

對 Transact-SQL 實(shí)現(xiàn)與 Microsoft Visual C# 和 Microsoft Visual C++ 語言中的異常處理類似的錯(cuò)誤處理。Transact-SQL 語句組可以包含在 TRY 塊中。如果 TRY 塊內(nèi)部發(fā)生錯(cuò)誤,則會(huì)將控制傳遞給 CATCH 塊中包含的另一個(gè)語句組。

--=========================================================

在TRY CATCH未出現(xiàn)之前,我們使用@@ERROR,ERROR_STATE()等來判斷語句是否正常運(yùn)行,再根據(jù)情況來處理事務(wù),隨著TRY CATCH的出現(xiàn),我們可以將事務(wù)語句寫成如下方式:

--開啟事務(wù)BEGIN TRAN BEGIN TRY    --執(zhí)行一些邏輯操作    INSERT INTO TB1(ID)VALUES(1)    --提交事務(wù)    COMMIT TRANEND TRYBEGIN CATCH    --回滾事務(wù)    ROLLBACK TRANEND CATCH

可當(dāng)我們執(zhí)行以下語句(不創(chuàng)建臨時(shí)表#TB)

BEGIN TRAN BEGIN TRY    INSERT INTO #TB SELECT 1        PRINT 'COMMIT TRAN';        COMMIT TRAN;END TRYBEGIN CATCH    SELECT ERROR_MESSAGE() AS ErrorMessage    ,ERROR_SEVERITY() AS ErrorSeverity    ,ERROR_STATE() AS ErrorState    PRINT 'ROLLBACK TRAN';    ROLLBACK TRAN;END CATCH

由于#TB沒有創(chuàng)建,因此在執(zhí)行中發(fā)生異常,錯(cuò)誤提示如下:

消息 102,級別 15,狀態(tài) 1,第 24 行“對”附近有語法錯(cuò)誤。

這個(gè)錯(cuò)誤很容易理解,因?yàn)?TB不存在,但這不是重點(diǎn),重點(diǎn)是CATCH部分的語句沒有被執(zhí)行,事務(wù)沒有被提交也沒有被回滾(如果程序中有類似問題,那就嚴(yán)重咯)。

繼續(xù)閱讀MSDN,可以找到如下解釋:

不受 TRY…CATCH 構(gòu)造影響的錯(cuò)誤TRY…CATCH 構(gòu)造在下列情況下不捕獲錯(cuò)誤:嚴(yán)重級別為 10 或更低的警告或信息性消息。嚴(yán)重級別為 20 或更高且終止會(huì)話的 SQL Server 數(shù)據(jù)庫引擎任務(wù)處理的錯(cuò)誤。如果所發(fā)生錯(cuò)誤的嚴(yán)重級別為 20 或更高,而數(shù)據(jù)庫連接未中斷,則 TRY…CATCH 將處理該錯(cuò)誤。需要關(guān)注的消息,如客戶端中斷請求或客戶端連接中斷。當(dāng)系統(tǒng)管理員使用 KILL 語句終止會(huì)話時(shí)。如果以下類型的錯(cuò)誤的發(fā)生級別與 TRY…CATCH 構(gòu)造的執(zhí)行等級相同,則 CATCH 塊不會(huì)處理這些錯(cuò)誤:編寫錯(cuò)誤,例如禁止運(yùn)行批處理的語法錯(cuò)誤。語句級重新編寫過程中出現(xiàn)的錯(cuò)誤,例如由于名稱解析延遲而造成在編寫后出現(xiàn)對象名解析錯(cuò)誤。這些錯(cuò)誤會(huì)被返回到運(yùn)行批處理、存儲(chǔ)過程或觸發(fā)器的級別。

經(jīng)過對比分析,我們遇到的問題應(yīng)該屬于“語句級重新編寫過程中出現(xiàn)的錯(cuò)誤,例如由于名稱解析延遲而造成在編寫后出現(xiàn)對象名解析錯(cuò)誤。”的情況。

--==============================================================

如果有類似的問題,我們應(yīng)該如何處理呢?

解決辦法1: 在對#TB處理前先判斷其是否存在

解決辦法2:將對#TB的操作語句放入的EXEC(@SQL)

BEGIN TRAN BEGIN TRY    EXEC('INSERT INTO #TB SELECT 1')        PRINT 'COMMIT TRAN';        COMMIT TRAN;END TRYBEGIN CATCH    SELECT ERROR_MESSAGE() AS ErrorMessage    ,ERROR_SEVERITY() AS ErrorSeverity    ,ERROR_STATE() AS ErrorState    PRINT 'ROLLBACK TRAN';    ROLLBACK TRAN;END CATCH

執(zhí)行以上代碼,會(huì)發(fā)現(xiàn)同樣是嚴(yán)重級別16的錯(cuò)誤,這次可以被傳遞到CATCH塊中處理。--=======================================================

很多人說細(xì)節(jié)決定成敗,學(xué)習(xí)SQL SERVER的路上,有很多類似的小知識(shí)點(diǎn),平時(shí)很難遇到,遇到時(shí)也很容易顛覆下我們自認(rèn)為的“真理”,這個(gè)時(shí)候,多看看MSDN還是很管用的!


發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 聂拉木县| 云林县| 阿拉尔市| 九龙城区| 洛川县| 道真| 绥阳县| 大田县| 县级市| 固原市| 绍兴县| 乐亭县| 石泉县| 皮山县| 商水县| 师宗县| 黔西| 南召县| 平顺县| 金平| 剑河县| 霍山县| 榆中县| 阆中市| 农安县| 县级市| 石柱| 岑溪市| 五寨县| 丹东市| 永春县| 海伦市| 肇庆市| 咸丰县| 湖北省| 河西区| 上饶市| 永寿县| 榆中县| 翼城县| 涿鹿县|