Sql-Server

TRY CATCH 塊中的事務錯誤

  • September 22, 2016

如果出現問題,以下程式碼將返回此消息:

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;

此外,查看確切的錯誤消息會很有幫助,因此將PRINT塊中的替換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)

引用自:https://dba.stackexchange.com/questions/150373