SQL Server在存储过程中使用动态sql中的表值输入参数

时间:2015-09-16 08:00:23

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

我有一个存储过程,它有一个表值输入参数,该参数是从用户定义的表类型派生的。

我需要使用动态SQL中的输入表值参数从表中选择一些数据到表变量。这里的问题是没有动态SQL它工作正常,当我使用动态SQL无法编译存储过程。并且它抛出了这个错误:

  

Msg 137,Level 16,State 1,Procedure sp_CreateScenario_q2,Line 63
  必须声明标量变量“@paramTable”。

我必须使用动态SQL,因为我的表是动态生成的。

这是我的代码

ALTER  PROCEDURE [dbo].[sp_CreateScenario_q2]
(
    @bookId                                           INT,
    @scenarioName                                     NVARCHAR(100),
    @paramTable [planning].[HierarchyAllocationInput] READONLY,
    @userId                                           INT              
) 
AS 
BEGIN

DECLARE @DemandStructureId  INT,
@AreaCode           NVARCHAR(20),
@Query              NVARCHAR(MAX),
@BucketId                   INT;

DECLARE @DemandData TABLE(
FGDemandId nVARCHAR(100),
DemandQty DECIMAL(18,2),
ProductNo NVARCHAR(100),
LocationNo NVARCHAR(100),
Season NVARCHAR(100),
Year INT

);


SELECT  @DemandStructureId  = PlanningStructureId,@BucketId = BucketId
    FROM    [planning].[Book]
    WHERE   BookId = @bookId

    SELECT  @AreaCode           = PlanningAreaCode 
    FROM    [config].[PlanningStructure] LEFT JOIN 
            [config].[PlanningArea] ON  PlanningStructure.PlanningAreaId = PlanningArea.PlanningAreaId
    WHERE   PlanningStructureId = @DemandStructureId

    IF @BucketId = 1 
        BEGIN

        SET @Query = 'select d.FGDemandId,d.DemandQty,d.ProductNo,d.LocationNo,d.Season,d.Year 
                      from '+ @paramTable +'
                            left join [dbo].[SN_STAGING_ProductReference] pr ON 
                                    pr.ProductReferenceId = t1.ProductReferenceId
                            left join '+ quotename(@AreaCode) +'.[SN_STAGING_FGDemand] d ON
                                    d.HierarchyId = t1.PlanningHierarchyId 
                                AND ISNULL(d.ProductNo,'') = ISNULL(pr.ProductNo,'')
                                AND ISNULL(d.LocationNo,'')  = ISNULL(pr.LocationNo,'') 
                                AND d.Year = t1.PlanningYear
                                AND ISNULL(d.Season,'') = ISNULL(t1.PlanningSeason,'')
                                AND d.IsActive = 1'

            INSERT INTO @DemandData EXECUTE(@Query);



        END
SELECT * FROM @DemandData;
END

1 个答案:

答案 0 :(得分:0)

我有相同的用例,我从EXEC(query)切换到sp_executesql,它提供了在动态查询中布置参数的功能。

将您的代码作为实例,

SET @Query = 'select d.FGDemandId,d.DemandQty,d.ProductNo,d.LocationNo,d.Season,d.Year 
              from @dynamicParamTable 
              left join [dbo].[SN_STAGING_ProductReference] pr ON pr.ProductReferenceId = t1.ProductReferenceId 
              left join '+ quotename(@AreaCode) +'.[SN_STAGING_FGDemand] d ON d.HierarchyId = t1.PlanningHierarchyId 
                AND ISNULL(d.ProductNo,'') = ISNULL(pr.ProductNo,'')
                AND ISNULL(d.LocationNo,'')  = ISNULL(pr.LocationNo,'') 
                AND d.Year = t1.PlanningYear
                AND ISNULL(d.Season,'') = ISNULL(t1.PlanningSeason,'')
                AND d.IsActive = 1'

INSERT INTO @DemandData EXECUTE sp_executesql @Query, N'@dynamicParamTable [planning].[HierarchyAllocationInput] READONLY', @dynamicParamTable = @paramTable