存储过程中的 SET QUOTED_IDENTIFIER ON 不起作用

SET QUOTED_IDENTIFIER ON within the stored procedure is not working

我在存储过程中使用 FOR XML PATH,因此我需要将 QUOTED_IDENTIFIER 设置为 ON。我将它作为存储过程的第一条语句。

SET QUOTED_IDENTIFIER ON;

除了我第一次恢复我的数据库外,这一切都很好。

刚刚恢复数据库后,我检查了sp_helptext <SPName>,存储过程似乎没问题。

然而,当我从对象资源管理器浏览我的存储过程并单击“修改”时,它显示如下:

当我尝试使用 EXEC <SP_Name> 执行存储过程时,它抛出一个错误

SELECT failed because the following SET options have incorrect settings: 'QUOTED_IDENTIFIER'. Verify that SET options are correct for use with indexed views and/or indexes on computed columns and/or filtered indexes and/or query notifications and/or XML data type methods and/or spatial index operations.

有人可以指导我为什么 SQL 服务器要自己添加 SET QUOTED_IDENTIFIER OFF 吗?如何摆脱它?或者我们如何从存储过程中覆盖它?

如果我从顶部删除 SET QUOTED_IDENTIFIER OFF,re-execute/run 它将正常工作。

我的问题是 - 我们有在每次构建时运行 migrations/create 数据库的自动化流程,所以我无法一直手动删除它。 我也无法在数据库级别设置它。

我检查了它的数据库设置并将其设置为 false 但这应该没有任何区别吧?因为我在我的存储过程中专门设置了它。

提前致谢。

  1. QUOTED_IDENTIFIER 数据库设置无关。这只是一个默认值,每个客户端驱动程序在连接时设置 QUOTED_IDENTIFIER 并覆盖数据库默认值。

  2. 存储过程里面的SETQUOTED_IDENTIFIER是无关紧要的;删除它。

SET QUOTED_IDENTIFIER has no effect when it appears in the body of a stored procedure as static Transact-SQL.

SET QUOTED_IDENTIFIER

  1. 对创建存储过程的批处理有效的 QUOTED_IDENTIFIER 设置将存储在目录中,并由 SSMS 用于编写存储过程脚本。当前会话设置是什么、数据库默认设置是什么或 SSMS 查询选项是什么都无关紧要。如果它是在 QUOTED_IDENTIFIER ON 的情况下创建的,它将在 QUOTED_IDENTIFIER ON 的情况下编写脚本。您可以在 sys.sql_modules.
  2. 中查看存储的设置

例如

select uses_quoted_identifier
from sys.sql_modules
where object_id = object_id('MyProc')

所以,

However when I browse my stored procedure from the Object Explorer and click on "Modify", it [is scripted with QUOTED_IDENTIFER OFF].

如果 sys.sql_modules 中的设置与生成的脚本中的设置不同,那将是 SSMS/SMO 中的错误。

还有这个:

表示存储过程是在 QUOTED_IDENTIFIER OFF 的情况下创建的。如您所见,调用存储过程的会话的会话设置无关紧要。

When a stored procedure is created, the SET QUOTED_IDENTIFIER and SET ANSI_NULLS settings are captured and used for subsequent invocations of that stored procedure.

SET QUOTED_IDENTIFIER

此存储过程的设置还控制存储过程中动态 SQL 的 QUOTED_IDENTIFIER 设置。但在动态 SQL 中,您可以 更改 设置。

是的

My problem is - We have automated process which runs migrations/create database on every build

这个过程被破坏了,因为它在 QUOTED_IDENTIFIER 关闭的情况下创建你的过程。如果您无法修复它,您可以通过将 TSQL 推送到动态批处理中并在动态 SQL 中设置 QUOTED_IDENTIFIER ON 来解决它。例如

set quoted_identifier off
go
create or alter procedure foo
as
begin
  exec ('set quoted_identifier on; select * from "sys"."objects"')

end
go

exec foo --suceeds

你也可以让你的存储过程创建脚本依赖于 QUOTED_IDENTIFIER ON 所以你不可能在 QUOTED_IDENTIFIER OFF 的情况下创建它,例如

set quoted_identifier off
go
create or alter procedure foo
as
begin
  select * from "sys"."objects" 
end

失败

Msg 102, Level 15, State 1, Procedure foo, Line 4 [Batch Start Line 2]
Incorrect syntax near 'sys'.