Search code examples
mysqlmysql-error-1064stored-functions

MySQL select one record into variable inside of the function using if then else approach


I am trying to build a mysql function which, given input variables, is capable to go into one of the if branches and set a variable using a select. Then this variable should be returned. After browsing a bunch of manuals I settled on the code below:

create function dayssincelastmo(sedol varchar(255), currDate datetime, z_score double, groupnum int)
returns int
deterministic 
begin
    if zscore<0 then
        select datediff(p.`Period (Formatted)`, currDate) into @days
            from
                price as p
            where
                p.G_SEDOL = sedol
                and p.`Period (Formatted)`<=currDate
                and p.zscore<=z_score
                and p.`GRP MODEL NUM` = groupnum
                order by p.`Period (Formatted)`
                limit 1;
    end if;
    if zscore>=0 then
        select datediff(p.`Period (Formatted)`, currDate)  into @days
            from
                price as p
            where
                p.G_SEDOL = sedol
                and p.`Period (Formatted)`<=currDate
                and p.zscore>=z_score
                and p.`GRP MODEL NUM` = groupnum
                order by p.`Period (Formatted)`
                limit 1;
    end if;
return @days
end

As you see I limit number of outputs to 1 to get only one value from select in each of the branches. I also use if then else approach and close each of my if statements with end if.

But I get a error from the interpreter at line 15, which precisely has the limit 1; entry:

order by p.`Period (Formatted)`
**limit 1;**

Any advice on what is wrong?


Solution

  • Don't forget the semicolon (;) in RETURN statement:

    ...
    -- return @days
    return @days;
    ...
    

    UPDATE

    I can't reproduce the problem:

    mysql> DROP FUNCTION IF EXISTS `dayssincelastmo`;
    Query OK, 0 rows affected, 1 warning (0.00 sec)
    
    mysql> DELIMITER //
    
    mysql> create function dayssincelastmo(
        ->   sedol varchar(255),
        ->   currDate datetime,
        ->   z_score double,
        ->   groupnum int
        -> )
        -> returns int
        -> deterministic 
        -> begin
        ->     if zscore<0 then
        ->         select datediff(p.`Period (Formatted)`, currDate) into @days
        ->             from
        ->                 price as p
        ->             where
        ->                 p.G_SEDOL = sedol
        ->                 and p.`Period (Formatted)`<=currDate
        ->                 and p.zscore<=z_score
        ->                 and p.`GRP MODEL NUM` = groupnum
        ->                 order by p.`Period (Formatted)`
        ->                 limit 1;
        ->     end if;
        ->     if zscore>=0 then
        ->         select datediff(p.`Period (Formatted)`, currDate)  into @days
        ->             from
        ->                 price as p
        ->             where
        ->                 p.G_SEDOL = sedol
        ->                 and p.`Period (Formatted)`<=currDate
        ->                 and p.zscore>=z_score
        ->                 and p.`GRP MODEL NUM` = groupnum
        ->                 order by p.`Period (Formatted)`
        ->                 limit 1;
        ->     end if;
        -> return @days;
        -> end//
    Query OK, 0 rows affected (0.01 sec)
    
    mysql> DELIMITER ;