如何在postgresql函数中使用变量进行循环查询
我在postgresql(9.4.4版)中有一个相当复杂的函数,需要一些帮助 我有一个循环(下面有很多工作)在我的函数中声明如下:如何在postgresql函数中使用变量进行循环查询,postgresql,function,for-loop,plpgsql,dynamic-sql,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 varch
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
其中,ptable
、psymbol
、pstarttime
和pendtime
是从函数调用传递的变量
但我很高兴能够硬编码一个表,并使其他三件事基于一个变量:
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循环中使用变量的文档,因此这可能是不可能的。像这样更改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
您需要使用带有
EXECUTE
的动态SQL—但只用于参数化表名(或其他标识符)—不需要参数化值
并且不要将参数值连接到查询中。这比必要的成本更高,也更容易出错。改用新的
或使用:
相关的:
quote_literal(pendtime)| |“LOOP”
更改为quote_literal(pendtime)LOOP
之外,这一切都非常有效!我花了大约一个小时在谷歌上搜索如何做到这一点,最后我放弃了,并提出了要求。谢谢@BenHernandezYou应该提供一个完整的(最小的)函数。完整的标题和声明很重要。“而且永远是你的博士后版本。@欧文感谢你的反馈,我更新了这个问题,尽管你已经为我完美地回答了它。谢谢大家!<代码>行数据应声明为记录
。我冒昧地把它四舍五入。我不知道我可以用唱片。我根据找到的循环的另一个堆栈示例为查询结果创建了一个特定类型。使用该记录更具可读性。谢谢(再次!)我添加了手册的链接。@Erwin,在上面的一行中,我们不应该在quote|ident部分前面添加连接管道,如下所示吗?:选择datetime,value FROM'| | quote|ident(ptable)| |'
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;
EXECUTE format('
SELECT datetime, value FROM %I
WHERE symbol = $1
AND datetime between $2 AND $3', ptable)
USING psymbol, pstarttime, pendtime