消息137,必须声明标量变量

时间:2015-12-31 10:04:47

标签: sql-server

Declare @SKUCode1 varchar(30), @SKUCode2 varchar(30), @SKUCode3 varchar(30),
        @SKUCode4 varchar(30), @SKUCode5 varchar(30), @SKUCode6 varchar(30),
        @SKUCode7 varchar(30), @SKUCode7 varchar(30), @SKUCode8 varchar(30),
        @SKUCode10 varchar(30), @Temp_SKU varchar(30), @SKUCodeS varchar(30),
        @sp1 nvarchar(max),@Index int

Set @SKUCodeS = 'SKUCode'
Set @Index = 0

While @Index < 10   
Begin
    Set @Index = @Index + 1  

    Select @Temp_SKU = SKUCode  
    From dbo.UDA_Order  
    Where Areaname = 'LMC-TYRE BUILDING'

    Set @sp1 = 'Set'+' '+ @SKUCodeS+CONVERT(varchar,@Index)+' '+'='+' '+'@Temp_SKU'  

    Exec sp_executesql @sp1  
End

这是抛出错误

  

Msg 137,Level 15,State 2,Line 1
  必须声明标量变量“@Temp_SKU”

我不知道为什么会这样。

请帮忙。

3 个答案:

答案 0 :(得分:1)

好的,所以第一个任务 - 为每个变量分配适当的值,可以这样做:

--Sample data
declare @t table (SKUCode varchar(30) not null,MachineNo int not null)
insert into @t(SKUCode,MachineNo) values
('abc',1),
('def',2),
('ghi',3),
('jkl',4),
('mno',5),
('pqr',6),
('stu',7),
('vwx',8),
('uzA',9),
('BCD',10)

--Actual query
Declare @SKUCode1 varchar(30), @SKUCode2 varchar(30), @SKUCode3 varchar(30),
        @SKUCode4 varchar(30), @SKUCode5 varchar(30), @SKUCode6 varchar(30),
        @SKUCode7 varchar(30), @SKUCode8 varchar(30), @SKUCode9 varchar(30),
        @SKUCode10 varchar(30)

select @SKUCode1 = [1], @SKUCode2 = [2], @SKUCode3 = [3],
       @SKUCode4 = [4], @SKUCode5 = [5], @SKUCode6 = [6],
       @SKUCode7 = [7], @SKUCode8 = [8], @SKUCode9 = [9],
       @SKUCode10 = [10]
from (select * from @t pivot (MAX(SKUCode) for
      MachineNo in ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10])) u
      where 1=1 --Areaname, couldn't be bothered to include it here
      ) t

select @SKUCode5

打印mno,应该如此。我们已经避免了任何讨厌的循环,动态SQL等等。

现在问题的下一个部分是否已经轻松解决,我不知道。

答案 1 :(得分:0)

@Temp_SKU添加到动态执行的字符串中。但是,sp_execute不知道您的上下文,并且没有@TEMP_SKU的引用。尝试通过删除引号来添加@Temp_SKU的值而不是对变量的拒绝:

 Set @sp1 = 'Set'+' '+ @SKUCodeS+CONVERT(varchar,@Index)+' '+'='+' '+ @Temp_SKU  

在调用print之前尝试@sp1 sp_execute来查看实际执行的内容。

答案 2 :(得分:0)

您在动态查询中使用@Temp_SKU。当动态查询被触发时,你必须在动态查询的范围内声明它,我建议使用不同的名称:

Set @sp1 = 'Set'+' '+ @SKUCodeS+CONVERT(varchar,@Index)+' '+'='+' '+'@Temp_SKUDYN'  
Exec sp_executesql @sp1  N'@Temp_SKUDYN varchar(30)' @Temp_SKUDYN = @@Temp_SKU

但是,你究竟想做什么?看起来你正在尝试动态设置局部变量。在这种情况下,你必须使用类似的东西:

DECLARE @SQLString NVARCHAR(500)
DECLARE @ParmDefinition NVARCHAR(500)
DECLARE @IntVariable INT
DECLARE @Lastlname varchar(30)
SET @SQLString = N'SELECT @LastlnameOUT = max(lname)
                   FROM pubs.dbo.employee WHERE job_lvl = @level'
SET @ParmDefinition = N'@level tinyint,
                        @LastlnameOUT varchar(30) OUTPUT'
SET @IntVariable = 35
EXECUTE sp_executesql
@SQLString,
@ParmDefinition,
@level = @IntVariable,
@LastlnameOUT=@Lastlname OUTPUT
SELECT @Lastlname

(从here复制)

修改

现在完全不确定这将是一个解决方案。更好地解释一下你想要完成什么。

编辑2

我仍然认为它可能更容易,但至少更清楚(未经测试,可能需要一些工作):

Declare @SKUCode1 varchar(30), @SKUCode2 varchar(30), @SKUCode3 varchar(30),
        @SKUCode4 varchar(30), @SKUCode5 varchar(30), @SKUCode6 varchar(30),
        @SKUCode7 varchar(30), @SKUCode8 varchar(30), @SKUCode9 varchar(30),
        @SKUCode10 varchar(30), @Temp_SKU varchar(30), @SKUCodeS varchar(30),
        @sp1 nvarchar(max),@Index int

CREATE TABLE ##codes (i INT, Val VARCHAR(30))
;

Set @SKUCodeS = 'SKUCode'
Set @Index = 0

While @Index < 10   
Begin
    Set @Index = @Index + 1  

    Select @Temp_SKU = SKUCode  
    From dbo.UDA_Order  
    Where Areaname = 'LMC-TYRE BUILDING'
        AND MachineNumber = @Index

    Set @sp1 = 'insert into ##codes(i, Val) VALUES('+ @Index + ',' + @Temp_SKU + ' )'-- 'Set'+' '+ @SKUCodeS+CONVERT(varchar,@Index)+' '+'='+' '+'@Temp_SKU'  

    Exec sp_executesql @sp1  
END

SELECT      @SKUCode1 = 1
,           @SKUCode2 = 2
,           @SKUCode3 = 3
,           @SKUCode4 = 4
,           @SKUCode5 = 5
,           @SKUCode6 = 6
,           @SKUCode7 = 7
,           @SKUCode8 = 8
,           @SKUCode9 = 9
,           @SKUCode10 = 10
FROM        (
                SELECT  *
                FROM    ##codes AS C
                PIVOT   (
                            MAX(VAL)
                            FOR i IN ([1], [2], [3], [4], [5], [6], [7], [8], [9], [10])
                        ) p
            ) piv

DROP TABLE ##codes