列表/数组的PL / pgSQL控制结构

时间:2014-12-30 15:35:48

标签: postgresql for-loop arraylist plpgsql control-structure

可以在Postgres中使用这样的东西吗?这是我想要做的PL / SQL的例子:

PROCEDURE CREATE_PAYMENT(P_AMOUNT IN NUMBER,
                         P_INVOICE_LIST IN SIMPLEARRAYTYPE, 
                         P_AMOUNT_LIST IN NUMBER_TABLE -- pass list of amounts
                            .
                            .
                            .)

s_chk_amnt              NUMBER;

invoice_list SIMPLEARRAYTYPE;
amount_list NUMBER_TABLE;

BEGIN
      -- check if amount list is null or contains zeros
    IF p_amount_list IS NOT NULL AND p_amount_list.COUNT <> 0 THEN
      FOR r IN p_amount_list.FIRST..p_amount_list.LAST
      LOOP
        s_chk_amnt := s_chk_amnt + p_amount_list(r);
      END LOOP;
    END IF;

我可以将字符列表和数字列表声明为函数输入参数吗? 我找到了FOREACH element的一些示例,但我不知道如何从数字列表中获取某个元素,就像在Oracle中使用p_amount_list(r)一样。

1 个答案:

答案 0 :(得分:0)

CREATE OR REPLACE FUNCTION CREATE_PAYMENT(p_amount_list numeric[])
  RETURNS numeric AS
$func$
DECLARE
   s_chk_amnt numeric := 0; -- init variable!
   r          numeric;
BEGIN
-- IF p_amount_list <> '{}' THEN  -- just noise
   FOREACH r IN ARRAY p_amount_list
   LOOP
      s_chk_amnt := s_chk_amnt + r;
   END LOOP;
-- END IF;

RETURN s_chk_amnt;
END
$func$ LANGUAGE plpgsql

重点

  • Oracle的numbernumeric in Postgres。但如果您没有小数位数,则宁愿在Postgres中使用intbigintAbout type mapping between Oracle and Postgres.

  • Postgres没有"table types" like Oracle。在这种情况下,使用array types numeric数组:numeric[]

  • 表达式IF p_amount_list <> '{}' ...将排除NULL和“空数组”一样。无需像原件一样进行第二次检查。但是根本不需要IF。对于NULL或空数组,无论如何都不会输入循环。

  • r包含元素本身,而不是它的索引。 (因此它必须是匹配的数据类型。)

这将演示plpgsql函数中FOREACH循环的基本语法。否则它将是昂贵的废话,更好地用更简单和更快的方式取代:

SELECT sum(elem) AS sum_amount
FROM   unnest(p_amount_list) elem;