Search code examples
sqlfirebird

Can Firebirds SELECT FIRST accept a variable?


http://www.firebirdsql.org/refdocs/langrefupd20-select.html#langrefupd20-first-skip

The manual says that FIRST accepts "Any expression evaluating to an integer." Shouldn't this mean a variable too?

In the following stored procedure, I get an error trying to supply :DAYS to FIRST.

Token unknown - line 10, column 18
:

Line 10 column 18 is the : in front of DAYS...

SET TERM ^ ;

CREATE PROCEDURE P_STOCK_MDA 
 ( STOCK BIGINT, TRADE_DATE DATE, DAYS SMALLINT ) 
RETURNS 
 ( AVG_CLOSE NUMERIC(6,2) )
AS 
BEGIN
  SELECT AVG(STOCK_ADJ_CLOSE) FROM (
    SELECT FIRST :DAYS STOCK_ADJ_CLOSE
    FROM STOCK_DAILY yd 
    WHERE yd.STOCK_STOCK=:STOCK AND yd.TRADE_DATE<=:TRADE_DATE
    ORDER BY yd.TRADE_DATE DESC
  ) INTO AVG_CLOSE;
END^

Solution

  • You need to enclose the parameter in parentheses to get it working:

    SELECT FIRST (:DAYS) STOCK_ADJ_CLOSE
    

    Full code:

    SET TERM ^ ;
    
    CREATE PROCEDURE P_STOCK_MDA 
     ( STOCK BIGINT, TRADE_DATE DATE, DAYS SMALLINT ) 
    RETURNS 
     ( AVG_CLOSE NUMERIC(6,2) )
    AS 
    BEGIN
      SELECT AVG(STOCK_ADJ_CLOSE) FROM (
        SELECT FIRST (:DAYS) STOCK_ADJ_CLOSE
        FROM STOCK_DAILY yd 
        WHERE yd.STOCK_STOCK=:STOCK AND yd.TRADE_DATE<=:TRADE_DATE
        ORDER BY yd.TRADE_DATE DESC
      ) INTO AVG_CLOSE;
    END^
    
    SET TERM ; ^
    

    The documentation does say :

    If <int-expr> is an integer literal or a query parameter, the “()” may be omitted

    However I assume this only applies to the ? query parameter in DSQL, not to the named parameters in PSQL.