Plpgsql - 多次迭代记录集
Posted
技术标签:
【中文标题】Plpgsql - 多次迭代记录集【英文标题】:Plpgsql - Iterate over a recordset multiple times 【发布时间】:2014-09-17 16:42:50 【问题描述】:我有一张表,其中包含一系列月份的累积活动,例如
month | activity
1 月 15 日 | 20
2 月 15 日 | 22
我在另一个表中也有一系列阈值,例如50、100、200。我需要获取达到阈值的日期,即活动 >= 阈值。
我想到的方法是有一个 pgsql 函数读取阈值表,迭代该游标并将月份表中读取到游标,然后迭代这些行以计算阈值所在的月份到达。出于性能原因,我不是每次都选择月份表中的所有行,而是返回游标中的第一行并使用阈值表中的新值重新迭代。
这是解决问题的明智方法吗?这就是我到目前为止所拥有的 - 我得到了一个
ERROR: cursor "curs" already in use
错误。
CREATE OR REPLACE FUNCTION schema.function()
RETURNS SETOF schema.row_type AS
$BODY$
DECLARE
rec RECORD;
rectimeline RECORD;
notification_threshold int;
notification_text text;
notification_date date;
output_rec schema.row_type;
curs SCROLL CURSOR FOR select * from schema.another_function_returning_set(); -- this is months table
curs2 CURSOR FOR select * from schema.notifications_table;
BEGIN
OPEN curs;
FOR rec IN curs2 LOOP
notification_threshold := rec.threshold;
LOOP
FETCH curs INTO rectimeline; -- this line seems to be the problem - not sure why cursor is closing
IF notification_threshold >= rectimeline.activity_total THEN
notification_text := rec.housing_notification_text;
notification_date := rectimeline.active_date;
SELECT notification_text, notification_date INTO output_rec.notification_text, output_rec.notification_date;
MOVE FIRST from curs;
RETURN NEXT output_rec;
END IF;
END LOOP;
END LOOP;
RETURN;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
【问题讨论】:
【参考方案1】:select distinct on (t.threshold) *
from
thresholds t
inner join
months m on t.threshold < m.activity
order by t.threshold desc, m.month
【讨论】:
噢!我认为这样的事情可以工作,但我拒绝了它 - 永远不要低估 sql 的力量!它仅在我将其更改为months m on t.threshold < m.activity
时才有效 - 假设这与加入有关。 order by
子句在这里似乎也很重要。注意自我 - 理解这个查询!
@Stev_k 仅当我将其更改为months m on t.threshold < m.activity
时才有效当然是我的错误。但后来你必须改成order by t.threshold **desc**
,不是吗?
有趣的是,我没有。我本以为这是必要的,因为我认为 distinct 选择了第一个唯一条目,但它似乎对我来说可以正常工作而无需更改顺序 - 不知道为什么。以上是关于Plpgsql - 多次迭代记录集的主要内容,如果未能解决你的问题,请参考以下文章
如何在 VB.NET 中将 '<unnamed portal 1>' 转换为 plpgsql 函数的数据集