存储过程中的 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
但这应该没有任何区别吧?因为我在我的存储过程中专门设置了它。
提前致谢。
QUOTED_IDENTIFIER 数据库设置无关。这只是一个默认值,每个客户端驱动程序在连接时设置 QUOTED_IDENTIFIER 并覆盖数据库默认值。
存储过程里面的SETQUOTED_IDENTIFIER是无关紧要的;删除它。
SET QUOTED_IDENTIFIER has no effect when it appears in the body of a
stored procedure as static Transact-SQL.
- 对创建存储过程的批处理有效的 QUOTED_IDENTIFIER 设置将存储在目录中,并由 SSMS 用于编写存储过程脚本。当前会话设置是什么、数据库默认设置是什么或 SSMS 查询选项是什么都无关紧要。如果它是在 QUOTED_IDENTIFIER ON 的情况下创建的,它将在 QUOTED_IDENTIFIER ON 的情况下编写脚本。您可以在 sys.sql_modules.
中查看存储的设置
例如
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.
此存储过程的设置还控制存储过程中动态 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'.
我在存储过程中使用 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
但这应该没有任何区别吧?因为我在我的存储过程中专门设置了它。
提前致谢。
QUOTED_IDENTIFIER 数据库设置无关。这只是一个默认值,每个客户端驱动程序在连接时设置 QUOTED_IDENTIFIER 并覆盖数据库默认值。
存储过程里面的SETQUOTED_IDENTIFIER是无关紧要的;删除它。
SET QUOTED_IDENTIFIER has no effect when it appears in the body of a stored procedure as static Transact-SQL.
- 对创建存储过程的批处理有效的 QUOTED_IDENTIFIER 设置将存储在目录中,并由 SSMS 用于编写存储过程脚本。当前会话设置是什么、数据库默认设置是什么或 SSMS 查询选项是什么都无关紧要。如果它是在 QUOTED_IDENTIFIER ON 的情况下创建的,它将在 QUOTED_IDENTIFIER ON 的情况下编写脚本。您可以在 sys.sql_modules. 中查看存储的设置
例如
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.
此存储过程的设置还控制存储过程中动态 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'.