共用方式為


SQL Server 2016 中的「INSERT EXEC 失敗,因為預存程式更改了目標數據表的架構」錯誤

本文可協助您解決發生的問題,因為資料庫中使用查詢數據存放區功能的預存程式會定期失敗。

原始產品版本:SQL Server 2016 年
原始 KB 編號: 4465511

徵狀

請試想下列案例:

  • 您有使用查詢資料存放區功能的 Microsoft SQL Server 2016 資料庫。

  • 您有一個預存程式,可使用 INSERT...EXEC 語法呼叫另一個預存程式。

  • 查詢數據存放區功能會定期執行自動清除,因為它會增加到其設定的大小上限。 此外,查詢資料存放區狀態會從 READ_WRITE 變更為 READ_ONLY

在此案例中,父預存程式執行會定期失敗,而且您會收到類似下列的錯誤訊息:

Msg 556, Level 16, State 2, Line LineNumber
INSERT EXEC 失敗,因為預存程式更改了目標數據表的架構。

原因

自動清除程式會將計劃清除出查詢資料存放區。 查詢會遇到重新編譯作業,因為查詢數據存放區遺漏計劃。 不過,計劃仍會出現在程式快取中。 根據設計,當重新編譯作業發生時,SQL Server 擲回錯誤 556,以防止子程式重複執行。 這類重複作業會導致傳回不正確的結果。

解決方案

2016 SQL Server Service Pack 資訊

下列 Service Pack 中已修正此問題,SQL Server:

Service Pack 3 for SQL Server 2016

關於適用於 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_ONLY返回狀態時,READ_WRITE清除程式快取。

其他資訊

由於在 Microsoft SQL Server 2017 中對查詢資料存放區所做的變更,此問題不會在 2017 SQL Server 發生。 此問題在 2016 SQL Server 無法修正。