3

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

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

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

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

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

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

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

4

1 回答 1

3

您需要QUOTED_IDENTIFIER在创建ON存储过程A的位置。笔记:

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

这意味着,任何创建存储过程的存储过程都将传递在其自身创建期间有效的设置。例如:

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
于 2014-03-11T11:50:25.260 回答