SQL Server动态嵌套EXEC调用存储过程遇Msg2812错误,求排查方案
问题分析与解决方案
首先,你遇到的Msg 2812错误不是因为EXEC嵌套调用不支持,SQL Server完全允许嵌套执行存储过程。报错的核心原因是你执行动态SQL的方式错误,再加上代码里还有几处语法和逻辑问题,具体如下:
1. 动态SQL执行方式错误
你直接用EXEC @NewStoredProc来执行动态创建存储过程的语句是错误的:
- 当
EXEC后面跟变量时,SQL Server会把这个变量的值当作存储过程的名称去查找,而不是执行变量里的SQL语句。这就是为什么报错说找不到空名的存储过程——因为你的动态SQL字符串开头是空格,解析后被识别为空的存储过程名。 - 正确的做法是使用系统存储过程
sp_executesql来执行动态SQL字符串,它专门用于处理这类场景。
2. 代码里的语法与逻辑问题
你的动态SQL代码还有几处需要修正的地方:
- 拼写错误:
DECALRE应该改为DECLARE - 变量赋值错误:给
@MapTable和@MapDevlTable赋值时,需要把表名用单引号包裹成字符串,否则SQL会把[Map].['+@TableName+']当作对象引用而非字符串 INSERT语句里的SELECT('+@ColsToLoad+')多了一对括号,会导致语法错误,直接写SELECT '+@ColsToLoad+'即可
修正后的代码
DECLARE @TableName nvarchar(100) = 'YourTableName'; -- 替换成实际的表名 DECLARE @ColsToLoad nvarchar(max) = 'Col1, Col2, Col3'; -- 替换成实际的列名 DECLARE @NewStoredProc nvarchar(max) = N'CREATE PROCEDURE [Map].[Load' + @TableName + N'] AS BEGIN DECLARE @MapTable nvarchar(100) = N''[Map].[' + @TableName + N']'' DECLARE @MapDevlTable nvarchar(100) = N''[MapDevl].[' + @TableName + N']'' DECLARE @ShapesAreValid bit DECLARE @PointsAreValid bit EXEC @ShapesAreValid = Map.AdminServiceValidateShapes @TableName = @MapDevlTable EXEC @PointsAreValid = Map.AdminServiceValidatePoints @TableName = @MapDevlTable IF(@ShapesAreValid = 1 AND @PointsAreValid = 1) BEGIN INSERT INTO [Map].[' + @TableName + N'] SELECT ' + @ColsToLoad + N' FROM [MapDevl].[' + @TableName + N'] END END '; -- 用sp_executesql执行动态SQL创建存储过程 EXEC sp_executesql @NewStoredProc;
关于EXEC嵌套调用的补充说明
SQL Server完全支持EXEC的嵌套调用,嵌套深度最多可达32层。你代码里调用Map.AdminServiceValidateShapes和Map.AdminServiceValidatePoints的写法是完全合法的,这部分没有问题。
内容的提问来源于stack exchange,提问作者Adam Jean-Laurent
相关产品推荐
相关产品推荐

