为什么SQL Server使用XML数据类型方法要开启QUOTED_IDENTIFIER
底层逻辑解释
QUOTED_IDENTIFIER是SQL Server控制标识符解析规则的核心开关:
- 当设置为
ON时,双引号"被识别为标识符分隔符,用来包裹包含特殊字符、关键字的表名、列名等对象名,只有单引号'是字符串字面量的分隔符 - 当设置为
OFF时,双引号"被识别为字符串分隔符,和单引号作用完全相同
要求调用XML数据类型方法时必须开启QUOTED_IDENTIFIER ON是SQL Server引擎层面的强制约束,核心原因有两个:
1. 避免XQuery语法被错误解析
XQuery/XPath语法本身允许使用双引号包裹字符串字面量,比如常见的属性过滤写法:
SELECT @xml.value('(/Locations/LocId[@countryCode="USA"])[1]','varchar(100)')
如果QUOTED_IDENTIFIER为OFF,SQL引擎在预解析阶段就会把XQuery表达式中的双引号识别为SQL字符串的结束符,将上面的语句错误拆分为'(/Locations/LocId[@countryCode="'、USA、"])[1]'三个部分,直接破坏XQuery的结构,导致语法解析失败,甚至出现非预期的执行结果。
2. 统一高级功能的配置标准
包括XML数据类型方法、索引视图、计算列索引、筛选索引在内的高级功能,内部实现都依赖固定的标识符解析规则。SQL Server强制要求这些功能必须在QUOTED_IDENTIFIER ON的环境下运行,避免同一个语句因为连接配置不同出现完全不同的行为,降低元数据管理和执行计划复用的复杂度。
你碰到的报错就是SQL Server的前置校验触发的结果:只要语句中调用了XML类型的.nodes()、.value()等方法,引擎会先检查QUOTED_IDENTIFIER配置,不符合要求直接终止执行,不会进入后续的XQuery解析阶段,避免出现更难排查的异常。
修复方案
只需要把代码开头的SET QUOTED_IDENTIFIER OFF改为SET QUOTED_IDENTIFIER ON,或者直接删除该行(SSMS等默认客户端连接默认会开启该配置)即可正常运行。
内容的提问来源于stack exchange,提问作者joemac12

