Sql-Server-2014
無法完成游標操作,因為在聲明游標後表架構發生了變化
當我執行從多個連結伺服器提取資訊並聚合數據的儲存過程時,偶爾會收到此錯誤消息。它看起來類似於我下面的內容。
DECLARE Cur CURSOR FOR SELECT name FROM sys.servers WHERE is_linked = 1 AND (@Environments IS NULL OR name IN (SELECT Item FROM clrStringSplit(@Environments, ','))) OPEN cur FETCH NEXT FROM cur INTO @Environment WHILE @@FETCH_STATUS = 0 BEGIN BEGIN TRY SET @Query = ' EXEC ' + @Environment + '.db.dashboard.storedproc ''' + CAST(@StartDate AS VARCHAR(10)) + ''', ''' + CAST(@EndDate AS VARCHAR(10)) + '''' INSERT INTO #Table (Environment, Column1, Column2, Column3, Column4, Column5, Column6, Column7) EXEC(@Query) END TRY BEGIN CATCH PRINT 'There was an error trying to query against ' + @Environment PRINT ERROR_MESSAGE() END CATCH FETCH NEXT FROM cur INTO @Environment END
它在每台伺服器上呼叫的儲存過程在每台伺服器上都完全相同,並且是從 dbo 模式下的表中提取的基本選擇語句。它將“隨機”出錯,並顯示“無法完成游標操作,因為聲明游標後表模式已更改”的消息。有時它執行良好,有時則不然。每次執行時,即使背靠背有時會起作用,有時不會。什麼可能導致這種情況發生,為什麼它如此斷斷續續?對其中一台伺服器上的過程的任何給定呼叫都可能會生成錯誤。它嘗試查詢的伺服器並不總是會產生錯誤。
值得一提的是,我有幾個程序執行極其相似但從未產生問題的每個程序。但它們都在同一個模式(dbo)下,這是第一次使用不同的模式。
編輯 - 我忘了提到我曾嘗試使用 FAST_FORWARD 游標,但它似乎沒有幫助。
嘗試將游標顯式設置為
LOCAL STATIC FORWARD_ONLY
.我不知道您的連結伺服器上可能會發生哪些特定更改,或者該儲存過程可能會觸及什麼,但是靜態會複製數據,這樣游標就不會受到影響(好吧,不關心)任何這些變化。
這與
sp_MSforeachdb
導致它跳過數據庫的問題相同。他們在那裡使用了錯誤類型的游標,並且由於錯誤處理,自游標打開以來以任何方式觸及的數據庫都會被靜默地跳過。這就是為什麼我在 Brent Ozar Unlimited 的First Responder Kit中編寫了一個也可用的替代品- 並進行了一些方便的改進。順便說一句,有一種更好的方法可以在由變數提供的數據庫/伺服器上執行動態 SQL。這通常使得使用
sp_executesql
和傳遞強類型參數成為可能(而不是在所有地方加倍引號,將整數和日期轉換為字元串,等等)。DECLARE @exec nvarchar(512); ... while loop ... SET @exec = @Environment + N'.db.sys.sp_executesql'; INSERT INTO #Table ( Environment, Column1, Column2, Column3, Column4, Column5, Column6, Column7 ) EXEC @exec N'EXEC dashboard.storedproc @StartDate, @EndDate;', N'@StartDate datetime, @EndDate datetime', @StartDate, @EndDate;