如何在 postgresql 函数中使用变量进行循环查询
How do I use variables in a postgresql function for loop query
我在 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
其中 ptable
、psymbol
、pstarttime
和 pendtime
是从函数调用传递的变量。
但我很乐意硬编码一个 table 并让其他三件事基于一个变量:
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
是的,我知道我有一个以数字命名的 table,在我当前的设置中我无能为力。
当我尝试使用上述任一设置调用该函数时,我只是得到一个空白。任何帮助,将不胜感激。我找不到任何关于在 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
您需要动态 SQL 和 EXECUTE
- 但 仅 参数化 table 名称(或其他标识符) - 没有必要参数化值.
并且不将参数值连接到查询中。这比必要的更昂贵且容易出错。请改用 USING
clause of EXECUTE
。
FOR row_data IN
EXECUTE '
SELECT datetime, value FROM ' || quote_ident(ptable) || '
WHERE symbol =
AND datetime between AND '
USING psymbol, pstarttime, pendtime
LOOP
-- do stuff
END LOOP;
或使用format()
:
EXECUTE format('
SELECT datetime, value FROM %I
WHERE symbol =
AND datetime between AND ', ptable)
USING psymbol, pstarttime, pendtime
相关:
- The manual on
record
types
- Table name as a PostgreSQL function parameter
- plpgsql - using dynamic table name in declare statement
我在 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
其中 ptable
、psymbol
、pstarttime
和 pendtime
是从函数调用传递的变量。
但我很乐意硬编码一个 table 并让其他三件事基于一个变量:
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
是的,我知道我有一个以数字命名的 table,在我当前的设置中我无能为力。
当我尝试使用上述任一设置调用该函数时,我只是得到一个空白。任何帮助,将不胜感激。我找不到任何关于在 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
您需要动态 SQL 和 EXECUTE
- 但 仅 参数化 table 名称(或其他标识符) - 没有必要参数化值.
并且不将参数值连接到查询中。这比必要的更昂贵且容易出错。请改用 USING
clause of EXECUTE
。
FOR row_data IN
EXECUTE '
SELECT datetime, value FROM ' || quote_ident(ptable) || '
WHERE symbol =
AND datetime between AND '
USING psymbol, pstarttime, pendtime
LOOP
-- do stuff
END LOOP;
或使用format()
:
EXECUTE format('
SELECT datetime, value FROM %I
WHERE symbol =
AND datetime between AND ', ptable)
USING psymbol, pstarttime, pendtime
相关:
- The manual on
record
types - Table name as a PostgreSQL function parameter
- plpgsql - using dynamic table name in declare statement