更新失敗,因為以下 SET 選項的設置不正確:代理作業中的“QUOTED_IDENTIFIER”
簡而言之,我在表中添加了一個計算列,然後代理作業開始失敗並報告錯誤:
UPDATE 失敗,因為以下 SET 選項的設置不正確:‘QUOTED_IDENTIFIER’。驗證 SET 選項對於索引視圖和/或計算列上的索引和/或過濾索引和/或查詢通知和/或 XML 數據類型方法和/或空間索引操作是否正確。
$$ SQLSTATE 42000 $$(錯誤 1934)。
較早的一個問題表明,必須在 QUOTED_IDENTIFIER 設置為 ON 的情況下創建儲存過程。然而,就我而言,沒有儲存過程。一個範例代理作業有一個步驟,其中包含執行兩次更新的直接 SQL - 每次更新都針對我更改的表。該 SQL 中沒有一個包含雙引號字元(這是 QUOTED_IDENTIFIER 的主題)。
微軟文件說:
在計算列或索引視圖上創建或更改索引時,SET QUOTED_IDENTIFIER 必須為 ON。
…但是我只是添加了列(持久)。我沒有創建或更改任何索引。
- 為什麼在這種情況下會出現此錯誤?
- 我該如何解決這個問題?我是否需要重新創建所有代理作業,在我這樣做之前將 QUOTED_IDENTIFIER 切換為 ON?或者我是否需要在更改表以添加計算列之前打開 QUOTED_IDENTIFIER?
可能相關的是,以下 SQL 顯示了數據庫中的哪些對像在編譯時具有 QUOTED_IDENTIFIER ON(即在使用時將使用該值解釋)。從這裡我看到觸發器也受此設置的影響。也許代理作業更新正在呼叫某種相關的觸發器?但是,我確實注意到,所有對像都列為 uses_quoted_identifier = 1。換句話說,如果解決方案是在重新創建對象之前將 QUOTED_IDENTIFIER 設置為 ON 時重新創建對象,我看不出它會有什麼不同; 所有對像似乎都是以這種方式創建的。
SELECT uses_ansi_nulls, uses_quoted_identifier, name, * FROM sys.sql_modules -- WHERE object_id = object_id('SampleProcedure') left outer join sys.sysobjects on sql_modules.object_id = sysobjects.id
為什麼在這種情況下會出現此錯誤?
代理本身正在切換
QUOTED_IDENTIFIER
到OFF
.我在這裡寫過(注意不可讀的字型,不是我的選擇)。
以下是在 sql server 2012 到 sql server 2017 上執行的測試:
如果我在 ssms 查詢視窗中執行此查詢:
DECLARE @QUOTED_IDENTIFIER VARCHAR(3) = 'OFF'; IF ( (256 & @@OPTIONS) = 256 ) SET @QUOTED_IDENTIFIER = 'ON'; SELECT @QUOTED_IDENTIFIER AS QUOTED_IDENTIFIER;
結果顯示為:
QUOTED_IDENTIFIER ON
當我將查詢用於檢查作業中的引用標識符並執行它時,會發生這種情況:
create table dbo.QUOTEDIDENTIFIER_CHECK(QUOTEDIDENTIFIER varchar(3)); DECLARE @QUOTED_IDENTIFIER VARCHAR(3) = 'OFF'; IF ( (256 & @@OPTIONS) = 256 ) SET @QUOTED_IDENTIFIER = 'ON'; SELECT @QUOTED_IDENTIFIER AS QUOTED_IDENTIFIER; insert into dbo.QUOTEDIDENTIFIER_CHECK(QUOTEDIDENTIFIER) select @QUOTED_IDENTIFIER;
select * from dbo.QUOTEDIDENTIFIER_CHECK;
結果:
QUOTEDIDENTIFIER OFF
在跟踪代理時,您可以清楚地看到關閉引用標識符的語句。
我該如何解決這個問題?我是否需要重新創建所有代理作業,在我這樣做之前將 QUOTED_IDENTIFIER 切換為 ON?
要解決此問題,您必須向
SET QUOTED_IDENTIFIER ON;
代理作業步驟添加顯式語句。
就我而言,我必須添加到步驟:
SET ANSI_NULLS, QUOTED_IDENTIFIER ON;
然後創建計算列。
ALTER TABLE ...
這樣代理作業可以順利執行