共用方式為


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 及其元件的版本、版本和更新層級

因應措施

若要暫時解決此問題,請遵循下列步驟:

  1. 增加查詢數據存放區的大小。 這會降低查詢數據存放區清除計劃並進入 READ_ONLY 作業模式的頻率或可能性。

  2. 將錯誤處理新增至您的程式代碼以攔截錯誤 556,然後重新提交 INSERT EXEC 查詢。

  3. 當查詢資料存放區 READ_WRITEREAD_ONLY返回狀態時,清除程式快取。

其他資訊

由於對 Microsoft sql Server 2017 中查詢資料存放區所做的變更,因此 SQL Server 2017 不會發生此問題。