带有存储过程和表变量的动态sql查询

时间:2015-12-25 16:06:14

标签: sql-server stored-procedures dynamic-sql

我想动态调用存储过程,因为我的程序名称存储在某个地方,我还需要将该过程的结果存储到表变量中。因此我必须编写以下sql代码,

在以下代码中     @tblEmailIds是我要存储SP结果的表变量     @tempEmailSource是过程的名称     @tempRecipientsIdsCSV是我的SP接受的第一个参数     @ObjectMasterId是SP接受的第二个参数(可选)

DECLARE @tempTypeName NVARCHAR(100), 
            @tempTypeId INT,
            @tempEmailSource NVARCHAR(100),
            @tempRecipientsIdsCSV NVARCHAR(MAX),
            @tempIsObjectSpecific BIT,
            @sqlQuery NVARCHAR(MAX) = 'INSERT INTO @tblEmailIds '
SELECT TOP 1 @tempTypeName = NAME, 
@tempTypeId = Id,         
@tempEmailSource = EmailListSourceName 
FROM @tbleRecipientsTypes WHERE IsEmailIdsFetched = 0

    SELECT @tempRecipientsIdsCSV = SUBSTRING(
    (SELECT ',' + CAST(RT.EmailRecipientId AS NVARCHAR(50))
    FROM @tbleRecipientsTypes RT WHERE RT.Id = @tempTypeId
    ORDER BY RT.EmailRecipientId
    FOR XML PATH('')),2,200000)

    SELECT @tempRecipientsIdsCSV


    SET @sqlQuery = @sqlQuery + 'EXEC ' + @tempEmailSource +' ' +''''  +    @tempRecipientsIdsCSV +''''
    IF (@tempIsObjectSpecific = 1)
    BEGIN
        SET @sqlQuery = @sqlQuery + ' ' + @ObjectMasterId
    END

    PRINT @SQLQUERY

    EXECUTE SP_EXECUTESQL 
    @SqlQuery,'@IdsCSV NVARCHAR(MAX) OUTPUT,  
    @ObjectMasterId INT = NULL OUTPUT', @tblEmailIds

我收到以下错误

  

消息214,级别16,状态3,过程sp_executesql,第6行过程   期望参数' @ params'类型&n; ntext / nchar / nvarchar'。

2 个答案:

答案 0 :(得分:1)

将前缀N添加到@params的{​​{1}}。

您还需要存储SP_EXECUTESQL参数

的结果
OUTPUT

答案 1 :(得分:1)

这里有很多问题。

  1. 正如错误消息明确指出的那样,参数列表需要为NVARCHAR,因此只需在该字符串文字前加N(如@ VR46的答案中所述)。

  2. 表变量不会像您尝试使用它们那样工作。首先,您不要声明@tblEmailIds,但即使您这样做,表变量的范围也是本地的,并且它们不能用作OUTPUT参数。相反,您需要创建一个本地临时表(即#tblEmailIds)并执行INSERT INTO #tblEmailIds

  3. 您引用了另一个尚未声明或填充的表变量@tbleRecipientsTypes

  4. 您确实声明@tempIsObjectSpecific但从未设置它,因此始终为NULL

  5. 为什么@IdsCSV(在sp_executesql调用参数列表中)声明为OUTPUT?您不仅没有传递@tempRecipientsIdsCSV(在动态SQL中为@IdsCSV),甚至不需要成为参数,因为您直接将@tempRecipientsIdsCSV的值连接成动态SQL,动态SQL中没有@tempRecipientsIdsCSV变量开头。因此,请从参数列表中删除@IdsCSV NVARCHAR(MAX) OUTPUT,

  6. 你说“@tempRecipientsIdsCSV是我的SP接受的第一个参数”,但是你在代码中声明它,这会导致错误。

  7. 什么数据类型是@ObjectMasterId?你说它被传递到proc中,我看到它被连接到动态SQL中,所以它需要是一个字符串类型(即INT参数列表中显示的不是sp_executesql )或者它需要在CONVERT(NVARCHAR(10), @ObjectMasterId

  8. 如果传入@ObjectMasterId,为什么在OUTPUT参数列表中将其声明为sp_executesql?但更好的问题可能是:为什么你甚至将它传递到sp_executesql,因为你直接将它连接到动态SQL?动态SQL中没有使用@ObjectMasterId变量。