使用 PostgreSQL PL/pgSQL 在 For 循环中添加月份
Posted
技术标签:
【中文标题】使用 PostgreSQL PL/pgSQL 在 For 循环中添加月份【英文标题】:Add Months in a For Loop using PostgreSQL PL/pgSQL 【发布时间】:2021-09-15 15:25:03 【问题描述】:我正在学习 for 循环并尝试使用 PostgreSQL 创建一个 PL/pgSQL 块,该块将生成一个付款时间表。此循环运行 12 个月,直到余额为 0,并且每个月都会显示到期日期。
这是我目前所拥有的,但月份部分没有添加到 for 循环中,它只添加了一次。
DO $$
DECLARE
start_date DATE := '01-Jan-2021';
payment_due_date DATE;
due_date VARCHAR(25);
mon_pay_amt NUMERIC := 10;
total_mon_amt NUMERIC := 12;
bal_num NUMERIC :=0;
BEGIN
bal_num := mon_pay_amt * total_mon_amt;
due_date := start_date;
RAISE NOTICE 'Total Amount due in 12 Months: %', to_char(bal_num, '$999.99');
FOR i IN 1..total_mon_amt LOOP
bal_num := bal_num - mon_pay_amt;
payment_due_date := start_date + INTERVAL '1 MONTH';
RAISE NOTICE 'Payment Number: %', i ||' '|| 'Due Date: ' ||payment_due_date|| ' Payment Amount : ' || to_char(mon_pay_amt, '$99.99') ||' '||
'Balance ' || to_char(bal_num, '$999.99');
END LOOP;
END $$;
【问题讨论】:
那是因为你不断将'1 month'
添加到start_date
,它被固定为'01-Jan-2021'。您需要在循环中使用i
计数器。比如:start_date + INTERVAL i::varchar || ' ' || MONTH'
.
那么你有答案了吗?
【参考方案1】:
会这样工作:
DO
$$
DECLARE
start_date date := '2021-01-01'; -- always use ISO date format
payment_due_date date := start_date;
mon_pay_amt numeric := 10;
mon_pay_amt_text text := to_char(mon_pay_amt, '$90.99');
total_mon_amt int := 12;
bal_num numeric := mon_pay_amt * total_mon_amt;
BEGIN
RAISE NOTICE 'Total Amount due in 12 Months: %', to_char(bal_num, '$999.99');
FOR i IN 1 .. total_mon_amt LOOP
bal_num := bal_num - mon_pay_amt;
RAISE NOTICE '%', format('Payment Number: %s Due Date: %s Payment Amount: %s Balance %s'
, i
, payment_due_date
, mon_pay_amt_text
, to_char(bal_num, '$990.99'));
payment_due_date := payment_due_date + interval '1 month'; -- increment after?
END LOOP;
END
$$;
但考虑使用 generate_series()
而不是循环的基于集合的方法:
DO
$$
DECLARE
start_date date := '2021-01-01';
payment_due_date date := start_date;
mon_pay_amt numeric := 10;
mon_pay_amt_text text := to_char(mon_pay_amt, '$99.99');
total_mon_amt int := 12;
bal_num numeric := mon_pay_amt * total_mon_amt;
BEGIN
RAISE NOTICE '%'
, (SELECT 'Total Amount due in 12 Months: ' || to_char(bal_num, '$999.99') || E'\n'
|| string_agg(format('Payment Number: %s Due Date: %s Payment Amount: %s Balance: %s'
, i
, payment_due_date + interval '1 month' * (i-1)
, mon_pay_amt_text
, to_char(bal_num - mon_pay_amt * i, '$990.99'))
, E'\n')
FROM generate_series(1, total_mon_amt) i
);
END
$$;
【讨论】:
以上是关于使用 PostgreSQL PL/pgSQL 在 For 循环中添加月份的主要内容,如果未能解决你的问题,请参考以下文章
如何在 PostgreSQL、PL/pgSQL 上执行匿名代码块切换 CASE 语句?
是否可以在 Spring Data JPA Repository 的 @Query 注释中使用 PostgreSQL 匿名块(PL/pgSQL)?
有没有为 PostgreSQL 开发的 PL/pgSQL 免费环境?