MySQL存储过程中的计算

时间:2018-11-22 02:03:12

标签: mysql stored-procedures

我正在创建一个存储过程,当您为某项输入一个类时,该存储过程将为您提供总价值。因此,我必须在SP中向查询添加计算。我不断收到一条错误消息,内容为:#1172-结果由多个行组成。我的猜测是,这是因为它从两个地方拉来获取产品。这是我的SP代码:

DELIMITER //
CREATE PROCEDURE totalValue (IN whichClass varchar(5),
                             OUT totalval int)
    BEGIN
        SELECT (price * numInStock) into totalval
        FROM hsitems
        WHERE itemClass = whichClass;
    END // 
DELIMITER ;

现在,当我输入任何内容并调用该过程时,我会收到错误消息。这是我尝试致电的方式:

CALL  totalValue('HW',@totalval); 
SELECT @totalval;

在将计算放入总值之前,是否需要将计算定义为AS?我尝试过,但仍然给我一条错误消息。

1 个答案:

答案 0 :(得分:2)

itemClass = 'HW'表中,hsitems基本上有多行。 SELECT .. INTO文档特别指出:

  

查询应返回一行。如果查询不返回任何行,则   发生错误代码1329的警告(无数据),并且变量值   维持不变。如果查询返回多行,错误1172   发生(结果包含多于一行)。如果有可能   该语句可能检索多行,您可以使用LIMIT 1来限制   结果设置为一行。

但是,根据您的变量名,我觉得您正在尝试SUM(price*numinstock)来获取总价值。这也将确保隐式聚合(GROUP BY)到一行。

此外,通过声明OUT totalval INT,您的输出将转换为int,并且十进制后将丢失值。因此,我将其更改为OUT totalval DECIMAL(10,2)。处理货币数字时,最好使用DECIMAL而不是FLOATDOUBLE之类的浮点类型。

DELIMITER //
CREATE PROCEDURE totalValue (IN whichClass varchar(5),
                             OUT totalval DECIMAL(10,2))
    BEGIN
        SELECT SUM(price * numInStock) into totalval  -- changed to SUM()
        FROM hsitems
        WHERE itemClass = whichClass;
    END // 
DELIMITER ;

如果您想将总和的格式设置为小数点后两位(例如货币),我们可以使用Format()函数。另外,请注意,现在输出将是字符串格式。

DELIMITER //
CREATE PROCEDURE totalValue (IN whichClass varchar(5),
                             OUT totalval VARCHAR(32))
    BEGIN
        SELECT FORMAT(SUM(price * numInStock), 2) into totalval 
        FROM hsitems
        WHERE itemClass = whichClass;
    END // 
DELIMITER ;