如何在postgresql函数中使用变量进行循环查询

时间:2015-12-30 09:04:40

标签: postgresql function for-loop plpgsql dynamic-sql

我在postgresql(版本9.4.4)中有一个相当复杂的功能,我需要一些帮助。

我在我的函数中声明了一个循环(下面有很多工作):

CREATE OR REPLACE function getRSI(
    psymbol varchar,
    pstarttime timestamp with time zone,
    pendtime timestamp with time zone,
    pduration double precision,
    ptable varchar
    )
 RETURNS SETOF rsi AS
 $BODY$
 declare
    row_data record;
    -- some variables
 begin
    FOR row_data IN SELECT datetime, value FROM "4" WHERE symbol = 'AAPL' 
    AND datetime BETWEEN '2015-11-23 09:30:00 -0500' AND 
    '2015-11-23 15:59:59-0500' LOOP
       -- enter code here
    END LOOP;
 end
 $BODY$ LANGUAGE plpgsql

这很有效,我可以得到我的功能结果并让它为我提供所有数字。

我想让循环像这样工作:

FOR row_data in select datetime, value from quote_ident(ptable) 
where symbol = quote_literal(psymbol) and datetime 
between quote_literal(pstarttime) AND quote_literal(pendtime) LOOP

其中ptablepsymbolpstarttimependtime是从函数调用传递的变量。

但是我很乐意对表进行硬编码并根据变量得到其他三个东西:

FOR row_data in select datetime, value from "4" where symbol =
quote_literal(psymbol) and datetime between quote_literal(pstarttime)
AND quote_literal(pendtime) LOOP

是的,我知道我有一个以数字命名的表格,在目前的设置中我无能为力。

当我尝试使用上述任一设置调用该函数时,我只是得到一个空白。任何帮助,将不胜感激。我找不到任何关于在for循环中使用变量的文档,因此可能无法实现。

2 个答案:

答案 0 :(得分:6)

您需要使用EXECUTE的动态SQL - 但来参数化表名(或其他标识符) - 不需要参数化

并且将参数值连接到查询中。这比必要的更昂贵且容易出错。请改用USING clause of EXECUTE

FOR row_data IN
   EXECUTE '
    SELECT datetime, value FROM ' || quote_ident(ptable) || '
    WHERE  symbol = $1
    AND    datetime between $2 AND $3'
   USING psymbol, pstarttime, pendtime
LOOP
  -- do stuff
END LOOP;

或使用format()

   EXECUTE format('
    SELECT datetime, value FROM %I 
    WHERE  symbol = $1
    AND    datetime between $2 AND $3', ptable)
   USING psymbol, pstarttime, pendtime

相关:

答案 1 :(得分:1)

像这样改变你的for循环

FOR row_data in execute 'select datetime, value from "4" where symbol =' || 
quote_literal(psymbol)  || 'and datetime between' || quote_literal(pstarttime)
|| 'AND ' || quote_literal(pendtime) LOOP