Sql-Server

更新失敗,因為以下 SET 選項的設置不正確:代理作業中的“QUOTED_IDENTIFIER”

  • September 7, 2020

簡而言之,我在表中添加了一個計算列,然後代理作業開始失敗並報告錯誤:

UPDATE 失敗,因為以下 SET 選項的設置不正確:‘QUOTED_IDENTIFIER’。驗證 SET 選項對於索引視圖和/或計算列上的索引和/或過濾索引和/或查詢通知和/或 XML 數據類型方法和/或空間索引操作是否正確。

$$ SQLSTATE 42000 $$(錯誤 1934)。

較早的一個問題表明,必須在 QUOTED_IDENTIFIER 設置為 ON 的情況下創建儲存過程。然而,就我而言,沒有儲存過程。一個範例代理作業有一個步驟,其中包含執行兩次更新的直接 SQL - 每次更新都針對我更改的表。該 SQL 中沒有一個包含雙引號字元(這是 QUOTED_IDENTIFIER 的主題)。

微軟文件說:

在計算列或索引視圖上創建或更改索引時,SET QUOTED_IDENTIFIER 必須為 ON。

…但是我只是添加了列(持久)。我沒有創建或更改任何索引。

  1. 為什麼在這種情況下會出現此錯誤?
  2. 我該如何解決這個問題?我是否需要重新創建所有代理作業,在我這樣做之前將 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_IDENTIFIEROFF.

我在這裡寫過(注意不可讀的字型,不是我的選擇)。

以下是在 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 ...

這樣代理作業可以順利執行

引用自:https://dba.stackexchange.com/questions/257629