我正在使用 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
中关闭 to CATCH
,插入无法说明我引用的标识符没有正确设置,尽管它设置在TRY
to的开头ON
。
这是设计使然:
因此, 的行为
QUOTED_IDENTIFIER
取决于批处理的解析,而不是执行。解析批处理开始时的默认值来自当前的连接设置。@@OPTIONS
仅向您显示当前默认值,如果解析了批处理,则将使用该默认值。这就是为什么 SSMS 总是放在SET
一个单独的批次中。的执行与
SET
的行为无关@@OPTIONS
,除了更改以后批次的默认值。您可以在 db-fiddle 中看到这一点
Charlieface的回答似乎已经适当地解释了您在使用时描述的行为的原因
SET QUOTED_IDENTIFIER
,所以如果您需要在 SP 中使用它,我将留下一个您可以使用的方法:建议的解决方案
在另一个过程中隔离您的批处理的一部分,并从
QUOTED_IDENTIFIER
需要OFF
这样的过程中调用它:db<>fiddle - 在您的计算机上运行 2 个不同的会话,因为我无法使其在 dbfiddle 上正常运行。