使用带有动态SQl的变量

时间:2018-03-09 10:26:16

标签: sql sql-server sql-server-2008 sql-server-2012

您好我在我的商店中使用动态查询过程使用以下语法

`   

    set @query =N'Select  ComponentName, '+ @cols +' From (
    Select Sum('+ @Sum_cols +') As Comp_stock,Com.ComponentName ,BB.BB_Name  
    from Z_DM_DR_CM_STOCK COM
    Inner Join BLOOD_BANK_MASTER BB on COM.BB_srno =BB.BB_SRNO
    where Com.Trans_date ='''+ Convert(Varchar(10), @Trans_Date,126) +'''
    AND   (  @BG  = ''''OR  COM.BGName =''' + @BG +'''

    )Group by Com.ComponentName,BB.BB_Name  ' +
    ')As sourcetable 
    PIVOT
    (
    SUM([Comp_stock]) FOR [BB_Name] IN ('+ @cols +')
    ) As PIVOTTABLE order by ComponentName'

  execute(@query)`

禁止给出错误

必须声明标量变量" @ BG"。

和@BG是输入参数

任何人都可以帮忙吗?

1 个答案:

答案 0 :(得分:1)

您有AND ( @BG = ''''OR COM.BGName =''' + @BG +'''行。动态SQL中未声明“@BG”。你需要像以后在同一行中那样传递它:

AND   ( '' +  @BG + '' = '''' OR  COM.BGName =''' + @BG +'''

但是,此查询似乎对SQL注入开放;参数化你会好得多:

SET @query = N'
SELECT ComponentName,
        '+ @cols + N'  --This might need to be changed as well, but i don''t know how you''re generating this and I''m not guessing
FROM (SELECT SUM(('+ @Sum_cols + N') AS Comp_stock, --This might need to be changed as well, but i don''t know how you''re generating this and I''m not guessing
             Com.ComponentName,
             BB.BB_Name  
      FROM Z_DM_DR_CM_STOCK COM
           INNER JOIN BLOOD_BANK_MASTER BB ON COM.BB_srno =BB.BB_SRNO
      WHERE Com.Trans_date = @sTrans_date
        AND (@sBG = '''' OR COM.BGName = @sBG )
      GROUP BY Com.ComponentName,
               BB.BB_Name) AS sourcetable 
PIVOT (
    --This might need to be changed as well, but i don''t know how you''re generating this and I''m not guessing
    SUM([Comp_stock]) FOR [BB_Name] IN ('+ @cols + N')) AS PIVOTTABLE
ORDER BY ComponentName';

EXEC sp_executesql @query, N'@sBG int, @sTrans_date date', @sBG = @BG, @sTrans_Date = @trans_date; --I have guessed your data types

注意(因为我知道人们习惯于不会阅读他们在代码中留给他们的评论)我不知道@BG@Trans_date的数据类型是什么,因此我已经讨论过了它们分别是intdate。如果我猜错了,你需要改变它。

您可以从评论中看到,您还需要查看如何将列的值添加到查询中;您完成它的方式可能也可以打开注射,但我还没有看到您查询的早期部分。