Sql-Server
TRY CATCH 塊中的事務錯誤
如果出現問題,以下程式碼將返回此消息:
EXECUTE 之後的事務計數表明 BEGIN 和 COMMIT 語句的數量不匹配。先前計數 = 0,目前計數 = 1。
OPEN extensionViews FETCH NEXT FROM extensionViews INTO @Viewname WHILE @@FETCH_STATUS = 0 BEGIN BEGIN TRY exec sp_refreshview @Viewname END TRY BEGIN CATCH print 'ERROR sp_refreshview' END CATCH FETCH NEXT FROM extensionViews INTO @Viewname END CLOSE extensionViews DEALLOCATE extensionViews
我已經發現隱式事務有問題,但我並不完全理解它。
在 CATCH 的情況下,我是否必須明確地回滾交易?這是否意味著我必須明確地啟動事務以及在游標內回滾這個命令而不是全部?
鑑於以下資訊:
先前計數 = 0,目前計數 = 1。
這意味著
sp_refreshview
正在打開一個顯式事務但遇到未處理的異常,因此它不會自己做ROLLBACK
。“Previous count = 0”表示您的程式碼沒有創建事務。這不是您可以在程式碼中修復的問題,因為子程序必須以與
@@TRANCOUNT
開始時相同的方式退出。我懷疑您是否能夠添加一個ROLLBACK
,甚至是一個BEGIN TRAN
然後ROLLBACK
來幫助這個。至少,您需要找出導致問題的視圖。您可以通過在執行之前列印賦予該系統儲存過程的視圖名稱來做到這一點
sp_refreshview
,特別是如果錯誤是少數幾個不能被TRY...CATCH
構造擷取的錯誤之一。只需在後面添加以下語句BEGIN TRY
:RAISERROR(N'View: %s', 10, 1, @ViewName) WITH NOWAIT;
此外,查看確切的錯誤消息會很有幫助,因此將
CATCH
為以下查詢:SELECT @Viewname AS [ViewName], ERROR_NUMBER() AS [ErrorNumber], ERROR_MESSAGE() AS [ErrorMessage];
您還可以將以下內容添加到
CATCH
塊中,但我懷疑它會解決這個問題:IF (@@TRANCOUNT > 0) BEGIN ROLLBACK; END;
PS 您應該對
sysname
包含 SQL Server 對象名稱的變數和列使用(全部小寫),因為這是系統表中用於對象名稱的數據類型。sysname
是 的別名NVARCHAR(128)
。