一個腳本中的多個 Set Quoted_identifier 採用最後一個?
我正在使用 SQL Server 2019,但發現了一個奇怪的行為。研究並沒有讓我更進一步。
有人可以解釋這種行為嗎?
SET QUOTED_IDENTIFIER ON; if ((256 & @@options) = 256) print '1- quoted_identifier is on' else print '1- quoted_identifier is off'; BEGIN TRY if ((256 & @@options) = 256) print '2- quoted_identifier is on' else print '2- quoted_identifier is off'; END TRY BEGIN CATCH if ((256 & @@options) = 256) print '3- quoted_identifier is on' else print '3- quoted_identifier is off'; -- SET QUOTED_IDENTIFIER OFF -- if ((256 & @@options) = 256) print '4- quoted_identifier is on' else print '4- quoted_identifier is off'; END CATCH
回報:
1- quoted_identifier is on 2- quoted_identifier is on
但以下程式碼:
SET QUOTED_IDENTIFIER ON; if ((256 & @@options) = 256) print '1- quoted_identifier is on' else print '1- quoted_identifier is off'; BEGIN TRY if ((256 & @@options) = 256) print '2- quoted_identifier is on' else print '2- quoted_identifier is off'; END TRY BEGIN CATCH if ((256 & @@options) = 256) print '3- quoted_identifier is on' else print '3- quoted_identifier is off'; SET QUOTED_IDENTIFIER OFF if ((256 & @@options) = 256) print '4- quoted_identifier is on' else print '4- quoted_identifier is off'; END CATCH
回報:
1- quoted_identifier is off 2- quoted_identifier is off
即使它沒有進入擷取!我肯定錯過了什麼。
我什至能夠將程式碼簡化為最簡單的:
SET QUOTED_IDENTIFIER ON; if ((256 & @@options) = 256) print '1- quoted_identifier is on' else print '1- quoted_identifier is off'; SET QUOTED_IDENTIFIER OFF if ((256 & @@options) = 256) print '2- quoted_identifier is on' else print '2- quoted_identifier is off';
結果:
1- quoted_identifier is off 2- quoted_identifier is off
我有一些使用 的程式碼
FOR XML
,這要求我將帶引號的標識符設置為 ON,但無論 XML 部分成功還是失敗,我都需要將其設置回 OFF。你會怎麼做?我的測試表明,如果我在
SET QUOTED_IDENTIFIER
中關閉 toCATCH
,插入無法說明我引用的標識符沒有正確設置,儘管它設置在TRY
to的開頭ON
。
Charlieface的回答似乎已經適當地解釋了您在使用時描述的行為的原因
SET QUOTED_IDENTIFIER
,所以如果您需要在 SP 中使用它,我將留下一個您可以使用的方法:建議的解決方案
在另一個過程中隔離您的批處理的一部分,並從
QUOTED_IDENTIFIER
需要OFF
這樣的過程中呼叫它:db<>fiddle - 在您的電腦上執行 2 個不同的會話,因為我無法使其在 dbfiddle 上正常執行。
對於頂級 ad-hoc 批處理解析開始使用會話的目前設置
QUOTED_IDENTIFIER
。在解析批處理時,任何出現的SET QUOTED_IDENTIFIER
都會從那時起更改解析行為,並為會話保存該設置。所以在批處理解析並執行後,會話的QUOTED_IDENTIFER
設置將根據SET QUOTED_IDENTIFIER
批處理中最後一次出現的設置。**因此, 的行為
QUOTED_IDENTIFIER
取決於批處理的解析,而不是執行。**解析批處理開始時的預設值來自目前的連接設置。**
@@OPTIONS
僅向您顯示目前預設值,**如果解析了批處理,則將使用該預設值。這就是為什麼 SSMS 總是放在SET
一個單獨的批次中。的執行與
SET
的行為無關@@OPTIONS
,除了更改以後批次的預設值。set QUOTED_IDENTIFIER on; create table "select"(i int); drop table "select"; GO set QUOTED_IDENTIFIER off; create table "select"(i int); drop table "select"; -- Incorrect syntax near 'select'. GO set QUOTED_IDENTIFIER off; if (1=0) begin set QUOTED_IDENTIFIER on; end create table "select"(i int); drop table "select"; GO set QUOTED_IDENTIFIER on; if (1=0) begin set QUOTED_IDENTIFIER off; end create table "select"(i int); drop table "select"; -- Incorrect syntax near 'select'. GO