SQL Server中EXEC调用存储过程需注意:①输出参数必须声明变量并加OUTPUT关键字;②捕获结果集须用临时表且结构严格一致;③跨库调用需三段式名称并授权;④嵌套深度不得超过32层。
SQL Server 中直接用
调用另一个存储过程是可行的,但实际写的时候容易出错——不是参数传不进去,就是结果拿不到,或者事务行为和预期不符。
EXEC 调用时必须显式处理输出参数
如果被调用的存储过程有
参数,调用方必须声明变量、加
关键字,缺一不可。漏掉任意一个都会导致参数值为
或报错。
(不能写成
)
被调用过程定义里也得是
,类型和方向都要对得上
想捕获结果集?得用临时表或表变量
本身不返回结果集给调用方;想把被调用过程的
结果存下来,只能靠中间容器。
结构必须完全一致:列名、数量、类型、顺序都不能差
推荐用
+
表变量(
)在 SQL Server 2005+ 也支持,但注意它不能用于
(会报错),只能用于
的变体如
,实用性低
跨数据库或 Schema 调用必须用三段式名称
不写全名很容易调错对象,尤其当两个库都有同名存储过程,或当前用户默认 schema 不是
时。
正确写法:
或
错误写法:
(依赖当前上下文,不稳定)
权限也要检查:
,否则报“拒绝访问”
嵌套深度超 32 层会直接失败
SQL Server 硬性限制嵌套调用最多 32 层,不是警告,是运行时报
类错误。递归调用或无意中形成环形依赖(A→B→C→A)最容易踩中。
用
在关键位置做日志或短路判断:
避免在循环体里无条件
另一个过程
调试时可用
快速确认当前嵌套层级
最常被忽略的是输出参数的
关键字和临时表结构一致性——这两处一错,过程看起来执行成功,数据却为空或类型不匹配,排查起来特别费时间。
EXECOUTPUTOUTPUTNULLDECLARE @val FLOAT;EXEC sp_Procedure1 @val OUTPUT;EXEC sp_Procedure1 @val;@param FLOAT OUTPUTEXECSELECTCREATE TABLE #tmp (...)INSERT INTO #tmp EXEC sp_NameDECLARE @t TABLE(...)INSERT ... EXECINSERT ... EXECUTEOPENROWSETdboEXEC [OtherDB].[dbo].[sp_Name]EXEC OtherDB..sp_NameEXEC sp_NameGRANT EXECUTE ON [OtherDB].[dbo].[sp_Name] TO [user]Msg 8152, Level 16@@NESTLEVELIF @@NESTLEVEL > 30 RAISERROR('Too deep', 16, 1)EXECSELECT @@NESTLEVELOUTPUT