坚持这个SQL错误:“必须声明标量变量@XYZ”

时间:2015-02-06 00:07:17

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

我正在研究这个查询一段时间,但无法弄清楚问题。我所要做的就是从表格(最大订单,制作该订单)获取信息,存储它并将结果作为消息输出到控制台上。谢谢你的帮助。

这是我的问题:

USE DB;

DECLARE @BigCustomer table(CustomerName varchar(50), Itemtotal smallmoney);

    INSERT @BigCustomer 
        SELECT (FirstName + ' ' + LastName), 
               MAX((ItemPrice - DiscountAmount) * Quantity)
    FROM Orders as o join customers as c 
            on o.CustomerID = c.CustomerID 
         join OrderItems as oi 
              on o.OrderID = oi.OrderID
    WHERE o.CustomerID = 3
    GROUP BY (FirstName + ' ' + LastName), 
             ((ItemPrice - DiscountAmount) * Quantity)

DECLARE @CN nvarchar(50);
SET @CN = (SELECT CustomerName FROM @BigCustomer)
DECLARE @IT smallmoney;
SET @IT = (SELECT ItemTotal FROM @BigCustomer)
DECLARE @PrintMessage nvarchar(50);
SET @PrintMessage = N'The largest order of ' + 
    CONVERT(nvarchar(50), @IT) + N'was made by ' + @CN;

GO
PRINT @PrintMessage

2 个答案:

答案 0 :(得分:0)

YUPPIE!我把它弄清楚了。我DECLARE d两个变量并分别分配参数而不是使用一个变量。

如果我运行查询,我会收到以下消息:

  

最大订单$ 342.30由Dave Hunter制作。

以下是查询:

我想我终于明白了。

DECLARE @LOrder表(OrdTot money,OrdID int);

INSERT @LOrder

SELECT SUM((OI.ItemPrice - OI.DiscountAmount)* OI.Quantity),OI.OrderID FROM OrderItems AS OI GROUP BY OrderID

DECLARE @CName varchar(100); DECLARE @OAmount money;

SET @CName =(SELECT TOP 1         C.FirstName +' ' + C.LastName         来自客户C JOIN在C.CustomerID = O.CustomerID上订购O在lo.OrdID = O.OrderID上加入@LOrder lo         ORDER BY lo.OrdTot DESC);

SET @OAmount =(选择TOP 1         OrdTot         来自@LOrder         订购BY OrdTot DESC);

PRINT' $'的最大订单+ convert(varchar(50),@ OAmount)+'是由' + @CName

答案 1 :(得分:0)

根据您发布的查询作为答案判断,您似乎很困惑。尝试一次做一件事来构建生成的脚本。首先,不要在开头使用变量,而是使用普通查询返回数据。

作为一个基本查询,使用一个只获得最大订单及其ID的查询。为此,仅使用OrderItems表,将数据分组为OrderID并将结果限制为最高订单总数就足够了:

SELECT TOP (1)
  OrderID,
  OrderTotal = SUM((ItemPrice - DiscountAmount) * Quantity)
FROM
  dbo.OrderItems
GROUP BY
  OrderID
ORDER BY
  OrderTotal DESC
;

为了找出上述查询返回订单的客户的ID,您可以向Orders添加联接。您还需要修改GROUP BY子句以将CustomerID包含在其中:

SELECT TOP (1)
  o.CustomerID,
  oi.OrderID,
  OrderTotal = SUM((oi.ItemPrice - oi.DiscountAmount) * oi.Quantity)
FROM
  dbo.OrderItems AS oi
  INNER JOIN dbo.Orders AS o ON oi.OrderID = o.OrderID
GROUP BY
  oi.OrderID,
  o.CustomerID
ORDER BY
  OrderTotal DESC
;

此时,您可以暂时将CustomerID存储到变量中,并在第二个查询中使用它来从Customers读取客户的名称。这不是必需的,因为您可以在单个查询中返回所有数据:

SELECT TOP (1)
  CustomerName = c.FirstName + ' ' + c.LastName,
  OrderTotal   = SUM((oi.ItemPrice - oi.DiscountAmount) * oi.Quantity)
FROM
  dbo.OrderItems AS oi
  INNER JOIN dbo.Orders AS o ON oi.OrderID = o.OrderID
  INNER JOIN dbo.Customers AS c ON o.CustomerID = c.CustomerID
GROUP BY
  oi.OrderID,
  o.CustomerID,
  c.FirstName,
  c.LastName
ORDER BY
  OrderTotal DESC
;

如您所见,另一个连接被添加到查询中,GROUP BY子句再次被修改,以包括列FirstNameLastName

现在是时候将变量赋值引入查询,这样就可以将结果作为一行返回,而不是将其存储起来然后再打印出来。

SELECT TOP (1)
  @Customer     = c.FirstName + ' ' + c.LastName,
  @LargestOrder = SUM((oi.ItemPrice - oi.DiscountAmount) * oi.Quantity)
FROM
  dbo.OrderItems AS oi
  INNER JOIN dbo.Orders AS o ON oi.OrderID = o.OrderID
  INNER JOIN dbo.Customers AS c ON o.CustomerID = c.CustomerID
GROUP BY
  oi.OrderID,
  o.CustomerID,
  c.FirstName,
  c.LastName
ORDER BY
  OrderTotal DESC
;

请注意,查询不使用WHERE过滤器。您不可能事先知道客户的ID。 TOP (1) + ORDER BY技术可让您找到它。