在postgreSQL中使用动态SQL执行函数时数据类型错误

时间:2014-04-30 05:51:51

标签: sql postgresql jasper-reports dynamic-sql

我编写了一个PostgreSQL函数,它正在从Jasper iReport中调用仪表板。当我尝试在pgAdmin中手动执行相同的函数时,我收到类型为numeric的无效语法的错误。请找到我的功能,如下所述:

CREATE OR REPLACE FUNCTION revenue_dm.trendQuery( IN monthin integer, IN yearin integer  )
  RETURNS TABLE(month1 numeric,year1 numeric,month2 numeric,year2 numeric,month3   numeric,year3 numeric ) AS
$BODY$
       DECLARE

        BEGIN

           month1='select extract (month from (select concat(monthin,''-'',15,''-'',yearin)::date)-30)::numeric';
           month2='select extract (month from (select concat(monthin,''-'',15,''-'',yearin)::date)-60)::numeric';
           month3='select extract (month from (select concat(monthin,''-'',15,''-'',yearin)::date)-90)::numeric';
           year1= 'select extract (year from (select concat(monthin,''-'',15,''-'',yearin)::date)-30)::numeric';
           year2= 'select extract (year from (select concat(monthin,''-'',15,''-'',yearin)::date)-60)::numeric';
           year3= 'select extract (year from (select concat(monthin,''-'',15,''-'',yearin)::date)-90)::numeric';

          RETURN QUERY EXECUTE month1;
          RETURN QUERY EXECUTE month2;
          RETURN QUERY EXECUTE month3;
          RETURN QUERY EXECUTE year1;
          RETURN QUERY EXECUTE year2;
          RETURN QUERY EXECUTE year3;
    END;
    $BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100
  ROWS 1000;

我正在使用以下查询在pgAdmin中执行我的功能。

 SELECT revenue_dm.trendQuery(04,2014);

执行该功能后,这是我得到的错误:

ERROR:  invalid input syntax for type numeric: "select extract (month from (select concat(monthin,'-',15,'-',yearin)::date)-30)::numeric"
CONTEXT:  PL/pgSQL function revenue_dm.trendquery(integer,integer) line 6 at assignment

我无法调试代码中的哪个位置,在此函数中使用动态SQL时出错了。

任何人都可以帮助我找出我在这个特定功能中出错的地方。

1 个答案:

答案 0 :(得分:2)

  1. 您不能在动态sql中使用外部变量。使用format()或类似的逃逸机制;或使用USING(首选)
  2. EXECUTE子句
  3. RETURNS TABLE(month1 numeric ...等于定义OUT参数,即month1 numeric。从这个角度来看,您无法将查询字符串分配给该变量,Postgres将无法尝试将其解析为数字。
  4. 只需运行一个

    RETURN QUERY EXECUTE 'SELECT <multiple fields> ...' USING monthin, yearin;
    

    编辑:刚刚意识到,你根本不应该做一个动态查询(这里不需要它们)

    只需运行一个

    RETURN QUERY SELECT <multiple fields> ...;