在SQL Server中,我常常會看到有些前輩這樣寫:
if ( @@error <> 0 ) ROLLBACK TRANSACTION T else COMMIT TRANSACTION T
一開始,我看見別人這么寫,我就想當然的以為它只是個計數器,每當檢測到一處錯誤時,@@error的值+1,不過就因為這個理所當然,所以杯具了...
實際上,它并不是一個計數器,它是一個動態的值,動態的標識最后一條SQL命令執行的結果,如果成功則為0,不成功則標識錯誤碼。所以,像上面這種寫法是不妥的,舉個例子,如下:
SET NOCOUNT ON ; SET XACT_ABORT ON ; -- 執行 Transact-SQL 語句產生運行時錯誤,則整個事務將終止并回滾 BEGIN TRANSACTION T UPDATE Test SET a = ' 已更新 ' WHERE a = ' 未更新 ' RAISERROR ( ' 不好意思,你沒有權限! ' , 16 , 1 )
SELECT GETDATE () if ( @@error <> 0 ) ROLLBACK TRANSACTION T else COMMIT TRANSACTION T
分析:
按我以前的理解來說,【?RAISERROR ('不好意思,你沒有權限!',16,1)?】這里拋出了一個錯誤,整個事務應該回滾才對,可是,它卻沒有回滾!!那么原因出在哪呢?原來,問題出在"SELECT GETDATE()"這句上面!因為執行 RAISERROR 語句時,@@error的值不為0(好像是5000),而當執行到下一句"SELECT GETDATE()"時,@@error的值又變為0了!所以,后面的if語句自然沒有捕捉到任何錯誤...
?
對策:
既然找到了原因,那解決辦法自然也少不了。用Try...CATCH語法就可以了,語句如下:
SET NOCOUNT ON ; SET XACT_ABORT ON ; -- 執行 Transact-SQL 語句產生運行時錯誤,則整個事務將終止并回滾 BEGIN TRY BEGIN TRANSACTION T UPDATE Test SET a = ' 已更新 ' WHERE a = ' 未更新 ' RAISERROR ( ' 不好意思,你沒有權限! ' , 16 , 1 ) SELECT GETDATE () COMMIT TRANSACTION T END TRY BEGIN CATCH DECLARE @msg nvarchar ( 2000 ) = ERROR_MESSAGE() -- 將捕捉到的錯誤信息存在變量@msg中 RAISERROR ( @msg , 16 , 1 ) -- 此處才能拋出(好像是這樣子....) ROLLBACK TRANSACTION T -- 出錯回滾事務 END CATCH
?
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
