"必须声明标量变量"执行存储过程时出错

时间:2017-01-11 15:22:57

标签: sql sql-server tsql stored-procedures sql-server-2012

我试图制作一个插入价格的程序:

ptrDst += dstMove[mask];

当我执行该程序时,它很好,但是当我运行这样的程序时:

create procedure prInsertPrice
@NuggetID varchar(5),
@Unit_Price money,
@Start_Date datetime,
@End_Date datetime
as
begin
DECLARE @date AS DATETIME
SET @date = GETDATE()
    if
        (
        (@NuggetID like 'N[0-9][0-9]')
        and
        (@Unit_Price is not null)
        and
        (@Start_Date is not null)
        )
    begin
        print 'Insert Success'
        insert NuggetPrice (NuggetId, Unit_Price, Start_Date, End_Date)
        values (@NuggetID, @Unit_Price, @Start_Date, @End_Date)
    end
    else
    begin
        print 'Failed to insert'
    end
end

我收到错误消息:

  

必须声明标量变量@date。

为什么会这样,我该如何解决问题?

3 个答案:

答案 0 :(得分:5)

exec语句中的@date与存储过程中的@date不同。

您应该执行以下操作:

DECLARE @date AS DATETIME
SET @date = GETDATE()
EXEC prInsertPrice 'N01', 20000, @date, null

答案 1 :(得分:2)

当你跑步时:

EXEC prInsertPrice 'N01', 20000, @date, null

您将变量@date作为第三个参数传递给存储过程,@Start_Date。这与您在存储过程本身中声明内部@date变量完全分开,该变量在调用过程之后被声明并初始化,因为它执行。

如果在调用存储过程之前尚未初始化作为参数传递给存储过程的@date变量,则会出现您所描述的错误。

因此,您需要首先声明并初始化此变量:

DECLARE @date DATETIME = '2017-01-01' -- You can whatever date value you require here
EXEC prInsertPrice 'N01', 20000, @date, null

这可以防止错误。

注意:如果您愿意,也可以将@date变量的声明和初始化分开:

DECLARE @date DATETIME
SET @date = '2017-01-01'

虽然在解决您的基本问题或阻止将错误数据插入NuggetPrice表中,但我同意Prdp建议在表中添加CHECK约束,例如:

ALTER TABLE NuggetPrice
  ADD CONSTRAINT CK_NuggetPrice CHECK (NuggetID LIKE 'N[0-9][0-9]' 
                                       AND Unit_Price IS NOT NULL 
                                       AND Start_Date IS NOT NULL) 

这也可以防止任何人插入与指定逻辑不一致的记录。

答案 2 :(得分:1)

已经有其他两个答案提供了有关错误原因的足够信息,所以我不打算谈论它。这是解决数据验证的不同方法

我建议您创建一个Stored Procedure来执行此操作,而不是创建Check constraint来限制将错误数据插入表中

ALTER TABLE NuggetPrice
  ADD CONSTRAINT CK_NuggetPrice CHECK (NuggetID LIKE 'N[0-9][0-9]' AND Unit_Price IS NOT NULL AND Start_Date IS NOT NULL) 

这将确保没有人在NuggetPrice

中插入错误数据