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

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

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

徵兆

試想以下情況:

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

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

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

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

訊息 556,層級 16,狀態 2,行號 LineNumber
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. 增加查詢數據存放區的大小。 這會降低 Query Data Store 清除該計劃並進入 READ_ONLY 模式的頻率或可能性。

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

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

其他資訊

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