【问题标题】:MySQL create function errorMySQL创建函数错误
【发布时间】:2012-10-17 22:02:40
【问题描述】:

我需要创建一个函数,根据书籍的主题给出书籍价格的平均值。这个函数的规则是:

a) 如果参数为 null,则返回 null

b) 如果参数与我们在主题表中的任何主题 id 都不匹配,则返回值 -2

c) 如果参数与我们在主题表中的主题 id 匹配,但我们没有任何书籍 该主题,返回值 -1

create function AvgPriceByTopic(
p_subject varchar(20))
RETURNS decimal(8,2)
begin
declare v_avgPrice decimal(8,2);
declare v_avgListPrice decimal(8,2);

if p_subject is null then
    set v_avgPrice := null;
elseif exists (
        select avg(list_price) into v_avgListPrice
        from books 
        where topic_id = p_subject
        group by book_id
        limit 1 ) then
    set v_avgPrice := v_avgListPrice;
else 
    set v_avgPrice := -2;
end if;

return v_avgPrice;
end;
#

我收到一条错误消息:

 ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
 corresponds to your MySQL server version for the right syntax to use near 
  'into v_avgListPrice from books' at line 11

有什么建议可以摆脱这个错误吗?有时我的语法有问题......提前谢谢。

【问题讨论】:

    标签: mysql function if-statement procedure


    【解决方案1】:

    首先,您需要像@dan 建议的那样将计算平均值的查询移到EXISTS 之外。

    但我在该查询中发现了一个问题:它按 book_id 分组并进行了限制,然后尝试将其限制在第一行。首先,这不会产生按主题的平均价格,因为它不是按主题分组的,它只会产生每本书的价格。请尝试以下操作:

    delimiter $$
    
    create function AvgPriceByTopic(
        p_subject varchar(20))
    RETURNS decimal(8,2)
    begin
    declare v_avgPrice decimal(8,2);
    declare v_avgListPrice decimal(8,2);
    
    if p_subject is null then
        set v_avgPrice := null;
    elseif not exists (select * from topics where topic_id = p_subject) then
        set v_avgPrice := -2;
    elseif not exists (select * from books where topic_id = p_subject) then
        set v_avgPrice := -1;
    else
        select avg(list_price) into v_avgListPrice
        from books
        where topic_id = p_subject
        group by topic_id;
    end if;
    
    return v_avgPrice;
    end$$
    
    delimiter ;
    

    记得更改分隔符,以便 MySQL 不会将函数中的分号解释为 create function 语句的结尾。

    【讨论】:

      【解决方案2】:

      由于“这样的 SELECT 必须将其结果返回到外部上下文”,请参阅 using select into using user-defined variables。我会尝试在第一个 if 语句之外提取选择,例如:

      select avg(list_price) into v_avgListPrice
              from books 
              where topic_id = p_subject
              group by book_id
              limit 1;
      if p_subject is null then
          set v_avgPrice := null;
      elseif v_avgListPrice is not null then
          set v_avgPrice := v_avgListPrice;
      else 
          set v_avgPrice := -2;
      end if;
      

      【讨论】:

      • 你试过去掉avg函数吗,比如:select list_price into @v_avgListPrice
      • 我刚刚做了。但我再次收到语法错误。但是,我不确定如果这是我想要的,我为什么要删除 avg。
      • 只是为了测试是不是因为你使用了聚合函数。
      • 您可以尝试在 if 之外提取选择吗?
      猜你喜欢
      • 2011-05-17
      • 2014-10-09
      • 1970-01-01
      • 2015-02-07
      • 2013-11-13
      • 2011-03-25
      • 2020-01-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多