我有一个存储过程[A],它创建了另一个存储过程[B]
[A]永远不会由最终用户运行,并且没有参数或其他不受信任的数据。取而代之的是,它仅由我用来自动执行复杂SP [B]的创建。[A]除非内部结构发生更改,否则总会有相同的结果。因此,我认为这是安全的。
[B]由于使用xml,因此要求Quoted_Identifiers处于启用状态。
如果我复制并粘贴生成的SP,它可以正常工作,但是如果我让[A]用EXEC创建它,则SP在运行时会失败。
我试过SET QUOTED_IDENTIFIERS ON在[B]内添加,但效果不明显。
SET QUOTED_IDENTIFIERS ON
如果我使用sp_ExecuteSQL,也曾在调用[B]之前尝试将其设置为on,但也会出现同样的问题,但这似乎也没有效果(但是为什么在始终处于on状态的上下文中会如此)
我的猜测是EXEC和sp_ExecuteSQL始终使用设置OFF,而SET命令则由解析器而不是SQL引擎本身处理。那么如何使EXEC正确创建proc?
您需要QUOTED_IDENTIFIER在ON其中A创建存储过程。笔记:
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