SQL Server 2016 中的「INSERT EXEC 失敗,因為預存程式改變了目標數據表的架構」錯誤
本文可協助您解決發生的問題,因為資料庫中使用查詢數據存放區功能的預存程式會定期失敗。
原始產品版本: SQL Server 2016
原始 KB 編號: 4465511
徵兆
試想以下情況:
您有Microsoft SQL Server 2016 資料庫,其使用查詢數據存放區功能。
您有預存程式,可使用
INSERT...EXEC
語法呼叫另一個預存程式。查詢數據存放區功能會定期執行自動清除,因為它會增加到其設定的大小上限。 此外,查詢資料存放區狀態會從
READ_WRITE
變更為READ_ONLY
。
在此案例中,父預存程式執行會定期失敗,而且您會收到類似下列的錯誤訊息:
訊息 556,層級 16,狀態 2,行行 編號
INSERT EXEC 已經失敗,因為預存程序已更改目標資料表的結構描述。
原因
自動清除程式會將計劃排清到查詢資料存放區外。 查詢遇到重新編譯作業,因為查詢數據存放區中遺漏了計劃。 不過,計劃仍存在於程式快取中。 根據設計,當重新編譯作業發生時,SQL Server 會擲回錯誤 556,以避免重複執行子程式。 這類重複作業會導致傳回不正確的結果。
解決方法
SQL Server 2016 的 Service Pack 資訊
SQL Server 的下列 Service Pack 已修正此問題:
SQL Server 2016 Service Pack 3
關於 SQL Server 的 Service Pack:
Service Pack 是累積的。 每個新的 Service Pack 都包含先前 Service Pack 中的所有修正程式,以及任何新的修正程式。 建議您套用該 Service Pack 的最新 Service Pack 和最新的累積更新。 安裝最新的 Service Pack 之前,您不需要安裝先前的 Service Pack。 如需最新 Service Pack 和最新累積更新的詳細資訊,請參閱下列文章中的表 1:
如何判斷 SQL Server 及其元件的版本、版本和更新層級
因應措施
若要暫時解決此問題,請遵循下列步驟:
增加查詢數據存放區的大小。 這會降低查詢數據存放區清除計劃並進入
READ_ONLY
作業模式的頻率或可能性。將錯誤處理新增至您的程式代碼以攔截錯誤 556,然後重新提交
INSERT EXEC
查詢。當查詢資料存放區
READ_WRITE
從READ_ONLY
返回狀態時,清除程式快取。
其他資訊
由於對 Microsoft sql Server 2017 中查詢資料存放區所做的變更,因此 SQL Server 2017 不會發生此問題。