如何用字符串变量实现无游标/循环的逐行存储过程调用
解决动态SQL批量调用存储过程的报错问题
你遇到的这个错误其实是SQL Server解析动态SQL的逻辑导致的:当你直接写EXEC @Query时,SQL会把变量里的内容当成链接服务器的名称去查找,而不是把它当作要执行的T-SQL语句,所以才会出现找不到'dbo'服务器的报错。
修正方案
要执行动态构建的SQL字符串,你需要用以下两种正确的方式之一,同时还要补上你之前拼接时漏掉的EXEC关键字(不然即使执行也会报错):
方式1:用括号包裹变量执行
这是比较直接的修改方式,只需要给变量加上括号,同时确保拼接的SQL里每个存储过程调用都带EXEC:
DECLARE @Query varchar(200); SELECT @Query = STUFF( (SELECT 'EXEC dbo.usp_TestSP ''' + Name + ''';' FROM dbo.test_user FOR XML PATH('')), 1, 0, '' ) -- 给变量加上括号,告诉SQL这是要执行的语句 EXEC (@Query)
方式2:使用sp_executesql(推荐)
sp_executesql是SQL Server专门用来执行动态SQL的系统存储过程,它支持参数化(虽然这个场景用不到,但在有参数的场景下能避免SQL注入,还能重用执行计划)。需要注意的是,它要求动态SQL变量是nvarchar类型:
DECLARE @Query nvarchar(200); -- 类型改为nvarchar SELECT @Query = STUFF( (SELECT 'EXEC dbo.usp_TestSP ''' + Name + ''';' FROM dbo.test_user FOR XML PATH('')), 1, 0, '' ) EXEC sp_executesql @Query
为什么之前的写法会报错?
再啰嗦一句:EXEC关键字后面如果直接跟变量名,SQL Server的语法规则是把这个变量当作链接服务器的名称,然后执行该服务器上的默认数据库的存储过程,这显然不是你想要的。只有用括号包裹变量,或者用sp_executesql,SQL才会把变量内容当成T-SQL语句来执行。
内容的提问来源于stack exchange,提问作者Deepanshu Tyagi
相关产品推荐
相关产品推荐

