使用exec重建存储过程时如何复用QUOTED_IDENTIFIER等原有配置
问题原因解析
GO不是T-SQL官方语法,只是SSMS、sqlcmd等客户端工具识别的批处理分隔符,直接放在EXEC()执行的动态SQL中,数据库引擎无法识别,会直接报语法错误。- 移除
GO后,SET语句和CREATE/ALTER PROCEDURE处于同一个查询批中,违反了CREATE/ALTER PROCEDURE必须是批内第一条语句的规则,因此触发第二个报错。
正确解决方案
存储过程的uses_ansi_nulls和uses_quoted_identifier配置,取的是存储过程创建时当前会话的全局配置,我们可以利用这个特性,分三次执行动态SQL即可:
- 先执行动态SQL设置当前会话的
ANSI_NULLS参数 - 再执行动态SQL设置当前会话的
QUOTED_IDENTIFIER参数 - 最后执行存储过程的创建语句,此时创建的存储过程会自动继承前两步设置的会话配置
示例代码
-- 从临时表读取的原始配置值,假设已经存入变量 DECLARE @uses_ansi_nulls BIT, @uses_quoted_identifier BIT, @ProcDefinition NVARCHAR(MAX) -- 1. 设置ANSI_NULLS EXEC(N'SET ANSI_NULLS ' + CASE WHEN @uses_ansi_nulls = 1 THEN N'ON' ELSE N'OFF' END) -- 2. 设置QUOTED_IDENTIFIER EXEC(N'SET QUOTED_IDENTIFIER ' + CASE WHEN @uses_quoted_identifier = 1 THEN N'ON' ELSE N'OFF' END) -- 3. 直接执行存储过程创建语句,自动继承当前会话的配置 EXEC(@ProcDefinition)
注意事项
- 存储过程定义变量
@ProcDefinition必须使用NVARCHAR(MAX)类型,避免超长定义被截断或者出现编码异常。 - 所有动态SQL执行都在同一会话中完成,前两步的配置不会失效,完全可以保证和原始存储过程的配置完全一致。
内容的提问来源于stack exchange,提问作者Murali Dhar Darshan
相关产品推荐
相关产品推荐

