如何在plpgpsql函数的RETURNS TABLE中添加字段,我要添加的值在函数内部执行的SELECT中不存在:
我有此功能,可以在开始日期和结束日期(纪元时间戳)之间的每“步”秒内采样作业使用的cpu和ram的总和:
CREATE OR REPLACE FUNCTION resources(start_date INTEGER, end_date INTEGER, step INTEGER)
RETURNS TABLE (
cpu bigint
, ram bigint) AS $$
DECLARE
counter INTEGER := 0 ;
BEGIN
counter := start_date;
LOOP
EXIT WHEN counter > end_date ;
RETURN QUERY EXECUTE
'SELECT sum(j_ram) as ram, sum(j_cpu) as cpu from jobs where j_start_time <= ' || counter || ' and j_end_time >= ' || counter;
counter := counter + step ;
END LOOP ;
END;
$$ LANGUAGE plpgsql;
输出结果类似于:
cpu | ram
-------+------
0 |
6 | 12000
6 | 11000
1 | 1000
如何在表中添加变量'counter'的值,使其类似于:
cpu | ram | counter
-------+-------+--------
0 | | 100
6 | 12000 | 110
6 | 11000 | 120
1 | 1000 | 130
答案 0 :(得分:1)
这里不需要动态SQL。而且,如果您忽略了这一点,则只需将变量添加到选择中即可:
CREATE OR REPLACE FUNCTION resources(start_date INTEGER, end_date INTEGER, step INTEGER)
RETURNS TABLE (
cpu bigint
, ram bigint
, counter bigint)
AS $$
DECLARE
counter INTEGER := 0;
BEGIN
counter := start_date;
LOOP
EXIT WHEN counter > end_date;
RETURN QUERY
SELECT sum(j_ram) as ram, sum(j_cpu) as cpu, counter
from jobs
where j_start_time <= counter
and j_end_time >= counter;
counter := counter + step;
END LOOP;
END;
$$ LANGUAGE plpgsql;
答案 1 :(得分:1)
您实际上不需要EXECUTE
,因为没有动态参数,例如表名,列名等。只有传递给where子句的值会发生变化。计数器可以是选择的一部分。
CREATE OR REPLACE FUNCTION resources(start_date INTEGER, end_date INTEGER,
step INTEGER)
RETURNS TABLE (
cpu bigint
, ram bigint
, counter int) AS $$
DECLARE
counter INTEGER := 0 ;
BEGIN
counter := start_date;
LOOP
EXIT WHEN counter > end_date ;
RETURN QUERY
SELECT sum(j_ram)::bigint as ram, sum(j_cpu)::bigint as cpu,
counter from jobs
where j_start_time <= counter
and j_end_time >= counter;
counter := counter + step ;
END LOOP ;
END;
$$ LANGUAGE plpgsql;
我建议您避免循环,使用generate_series
进行单个查询就足够了。该函数可以是一个简单的 SQL函数,除非您需要执行其他操作而不返回只是查询结果。
CREATE OR REPLACE FUNCTION resources2(start_date INTEGER, end_date INTEGER,
step INTEGER)
RETURNS TABLE (
cpu bigint
, ram bigint
, counter int) AS $$
SELECT sum(j_ram) :: BIGINT AS ram,
sum(j_cpu) :: BIGINT AS cpu,
g.counter
FROM jobs j
JOIN (SELECT generate_series(start_date, end_date, step) AS counter) g
ON j_start_time <= g.counter
AND j_end_time >= g.counter
GROUP BY g.counter
ORDER BY g.counter;
$$ LANGUAGE sql;