You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

强制参数化如何影响使用QUOTED_IDENTIFIER等SET选项的查询?

强制参数化与QUOTED_IDENTIFIER的冲突解析

问题场景

在AdventureWorks2022数据库中,使用简单参数化时,以下查询可正常执行:

USE [AdventureWorks2022]
GO

SET QUOTED_IDENTIFIER OFF

SELECT "True" FROM Person.Person WHERE FirstName = "John"

SET QUOTED_IDENTIFIER ON

但启用强制参数化后,执行同一查询会报错:

Invalid column name 'True'.

只要做以下任一修改,查询就能成功执行:

  • 移除末尾的SET QUOTED_IDENTIFIER ON
  • 在SELECT语句后添加GO

核心原因解析

这完全和强制参数化的工作机制相关,关键在于强制参数化对批处理的解析逻辑与QUOTED_IDENTIFIER设置的交互:

1. QUOTED_IDENTIFIER的基础作用

  • 当SET QUOTED_IDENTIFIER OFF时,SQL Server把双引号当作字符串分隔符(和单引号功能一致),所以"True"会被解析为字符串常量,"John"也会被当作查询条件的字符串值。
  • 当SET QUOTED_IDENTIFIER ON时,双引号会被识别为对象标识符(比如列名、表名),此时"True"会被当作列名查找,自然就会抛出“无效列名”的错误。

2. 强制参数化的批处理解析逻辑

  • 简单参数化模式:SQL Server会逐句解析执行批处理。SET QUOTED_IDENTIFIER OFF的设置会直接作用于后续的SELECT语句,执行完SELECT后才会执行SET QUOTED_IDENTIFIER ON,整个流程符合预期。
  • 强制参数化模式:SQL Server会在执行批处理前,先对整个批处理内容进行参数化转换。这个转换过程会使用会话初始的QUOTED_IDENTIFIER设置(默认是ON),而不会识别批处理中间的SET QUOTED_IDENTIFIER OFF设置。
  • 换句话说,强制参数化解析时,直接以ON的规则处理双引号,把"True"当成列名,所以触发了错误。

3. 修改后生效的原因

  • 移除末尾的SET QUOTED_IDENTIFIER ON:此时批处理中只有SET QUOTED_IDENTIFIER OFF和SELECT语句,强制参数化解析时能正确识别这个设置,将双引号当作字符串处理,查询正常执行。
  • 添加GO:GO是批处理分隔符,会把原批处理拆成两个独立部分:第一部分是SET QUOTED_IDENTIFIER OFF加SELECT语句,第二部分是SET QUOTED_IDENTIFIER ON。强制参数化会对每个独立批处理单独解析,第一个批处理的SET设置会被正常应用,因此SELECT语句能正确执行。

内容的提问来源于stack exchange,提问作者Ben

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 21:13:27