嵌套的sp_executesql不使用输出变量

时间:2016-06-05 09:07:30

标签: sql-server stored-procedures sp-executesql parameter-sniffing

我试图使用sp_executesql在另一个存储过程中调用存储过程(带有输出变量)。我写了以下内容,但仍然无法得到那个错误意味着什么

这将从网络服务代码中调用:

exec sp1 'obj1',@params 

此处objparams属于nvarchar(max)

sp1的定义是:

Alter procedure [dbo].[sp1 ]  
    @procname nvarchar(max),  
    @params nvarchar(max)  
as   
    declare @temp varchar(15)  

    if @procname = 'obj1'  
    begin  
        set @params = @params +  ',@Newval  varchar(15) output'  
        EXEC sp_executesql @sp2,@params,@Newval=@temp OUTPUT  
    end  

sp2的定义:

我将返回@Newval

我收到错误:

  

Msg 102,Level 15,State 1,Line 1
  ','。

附近的语法不正确

同样在2代替exec陈述,我试过以下:

 EXEC sp_executesql @sp2, @params, @temp OUTPUT; 

导致同样的错误。

set @sql='sp2,' + ' @params ' + ',@params,@temp OUTPUT'
EXEC sp_executesql (@sql)

也会导致相同的错误。

我需要在sp1中动态选择存储过程,params是一个nvarchar(max)参数及其值的字符串,其中一些是varchar并嵌入''value''格式但是这个字符串很好我可以用这个来调用底层的sp2。

其他信息,它有帮助。

EXEC sp_executesql @sp2,@params,@Newval=@temp OUTPUT  

这个@params是最终sp的键和值的组合。类似的东西:
'@ KEY1 = “一”,@ KEY2 = “B”'
等等,我无法预定@params,但它是动态的,它正在工作 当我用

运行它时很好
exec (@sql)     

格式化时整个名称,params嵌入在@sql

1 个答案:

答案 0 :(得分:0)

如果@params=''NULL,之前的@Newval无关紧要。我建议你查一下:

IF NULLIF(@params,'') IS NULL or @params IS NULL
SET @params = '@Newval  varchar(15) output'
ELSE 
SET @params = @params + ',@Newval  varchar(15) output'

你正在通过@sp2,也许你需要这个:

ALTER PROCEDURE [dbo].[sp1]  
    @procname nvarchar(max),  
    @params nvarchar(max)  
AS   
    DECLARE @temp varchar(15)

    IF @procname = 'obj1'  
    BEGIN  
        SET @params = @params +  ',@Newval  varchar(15) output'  
        EXEC sp_executesql N'EXEC sp2 @someparam1, @someparam2, @Newval varchar(15) OUTPUT', @params, @someparam1 = 1, @someparam2 = 2, @Newval=@temp OUTPUT  
    END  

修改

工作示例:

USE [AdventureWorks]
GO

DECLARE @procname nvarchar(max) = 'EXEC [dbo].[uspGetWhereUsedProductID] @StartProductID, @CheckDate',  
        @params nvarchar(max) = '@StartProductID int, @CheckDate date'

EXEC sp_executesql @procname, @params, @StartProductID = 1, @CheckDate = '2015-10-17'
GO