【问题标题】:MYSQL Result consisted more than one row when using mysql function in where clause在where子句中使用mysql函数时,MYSQL结果包含多于一行
【发布时间】:2019-08-01 07:43:08
【问题描述】:

我有一个计算产品价格的存储过程(函数)。

这是我的功能:

CREATE DEFINER=`root`@`localhost` FUNCTION `getWinnerPriceByProductId`(
    `p_product_id` INT


)
RETURNS float
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
    DECLARE v_winner_price FLOAT DEFAULT 0;
    DECLARE v_product_plan VARCHAR(255);

    SELECT ps.plan INTO v_product_plan FROM product_supplier ps WHERE ps.product_id = p_product_id AND ps.winner = 1;

    IF v_product_plan = 'Plan AB' THEN
        SELECT ps.wholesale_price INTO v_winner_price FROM product_supplier ps WHERE ps.product_id = p_product_id AND ps.winner = 1 LIMIT 1;
    ELSE
            SELECT ps.price INTO v_winner_price FROM product_supplier ps WHERE ps.product_id = p_product_id AND ps.winner = 1 LIMIT 1;
    END IF;

    RETURN v_winner_price;      
END

现在当我简单地调用这个函数时:

Select getWinnerPriceByProductId(1);

然后它返回正确的结果。

但是当我尝试在 where 子句中使用它时:

SELECT * FROM products p where getWinnerPriceByProductId(p.id) BETWEEN 1 AND 100;

然后我收到一条错误消息:

结果包含多行。

如果结果由多行组成,那么调用函数时的情况与第一种情况不同吗?为什么只有当我在某些查询中使用该函数时才会发生这种情况?我在这里做错了什么?

【问题讨论】:

  • 在第一个查询中,由于您在存储过程中声明了限制,它返回了 1 行,在第二个查询中,它也返回了 1 行,但是由于您已过滤到记录之间,这就是它返回的原因超过 1 行。此外,您在第一个查询中有特定的 p.id 值,它专门过滤了 1 条记录
  • 什么 MySQL 版本?
  • @tcadidot0 mysql 5.7
  • 你的函数返回 1 的结果是什么?
  • 最后,您的查询将只选择表中的所有条目,多次例如:SELECT * FROM products where 1.4 between 1 and 100; 所以条件匹配然后显示整个表。再次SELECT * FROM products where 5.5 between 1 and 100; 再次循环重复......这是你需要的吗?

标签: mysql stored-procedures stored-functions


【解决方案1】:

目前不需要创建函数。一旦 OP 提供更多信息,将编辑此答案。

-- function can be replaced into simple join query
select case when ps.plan='Plan AB' then ps.wholesale_price else ps.price end as 'winner_price' 
from product_supplier ps
join product p on ps.product_id=p.id
where ps.winner=1 
and p.id=1; -- this is what you are parsing into the function

【讨论】:

  • 谢谢。我认为这是该问题的最合适答案。但是,为了清楚起见,我已经简化了问题,但在实际情况下,价格计算涉及更多的保证金和佣金计算。我想我需要在这种情况下做一个函数。我很想知道如何使用函数来比较它在 where 子句中的结果。
  • 查看光标上的文档是否对您有帮助:dev.mysql.com/doc/refman/8.0/en/cursors.html
【解决方案2】:

SELECT * FROM products where getWinnerPriceByProductId(p.id) BETWEEN 1 AND 100;

什么是 p.id 我们没有为此创建别名?请确保此 SP 在 1 列 getWinnerPriceByProductId(p.id) 上返回。

【讨论】:

  • 我在问题中添加了别名,这是一个错字。是的,该函数在第一个查询中调用时返回单行。此外,我在每个 SELECT INTO 案例中都使用了限制 1。
猜你喜欢
  • 2014-11-30
  • 2023-03-21
  • 1970-01-01
  • 2012-03-19
  • 1970-01-01
  • 1970-01-01
  • 2014-10-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多