EXEC和Set Quoted_Identifier

时间:2014-03-11 11:22:33

标签: sql sql-server stored-procedures sp-executesql quoted-identifier

我有一个存储过程[A]创建另一个存储过程[B]

[A]永远不会被最终用户运行,也没有参数或其他不受信任的数据。相反,我只是使用它来自动创建复杂的SP [B]。 [A]除非改变内部结构,否则总会得到相同的结果。因此我认为这是安全的。

[B]要求Quoted_Identifiers为ON,因为它使用xml。

如果我复制并粘贴生成的SP,它可以正常工作但如果我让[A]用EXEC创建它,那么SP在运行时就会失败。

我尝试在[B]中添加SET QUOTED_IDENTIFIERS ON,但效果不明显。

如果我使用sp_ExecuteSQL,也会出现同样的问题 我也尝试在调用[B]之前设置它,但这似乎也没有效果(但为什么它会在它始终开启的上下文中)

我的猜测是EXEC和sp_ExecuteSQL总是使用OFF设置,SET命令由解析器而不是SQL引擎本身处理。那么我怎样才能让EXEC正确创建proc?

1 个答案:

答案 0 :(得分:2)

您需要QUOTED_IDENTIFIERON,其中创建了存储过程A。注意:

  

创建存储过程时,将捕获SET QUOTED_IDENTIFIER和SET ANSI_NULLS设置,并将其用于后续调用该存储过程。

通过暗示,这意味着创建存储过程的任何存储过程都将传递其自己创建期间生效的设置。 E.g:

set quoted_identifier on
go
create procedure ABC
as
    exec('create procedure DEF as')
go
set quoted_identifier off
go
exec ABC
go
select definition,uses_quoted_identifier from sys.sql_modules
where object_id=OBJECT_ID('DEF')

产生

definition                             uses_quoted_identifier
-------------------------------------- ----------------------
create procedure DEF as                1