PL/pgSQL control structures for lists / arrays

后端 未结 1 1139
不知归路
不知归路 2021-01-28 10:01

Is it possible to use something like this in Postgres? This is the example from PL/SQL what I want to do:

PROCEDURE CREATE_PAYMENT(P_AMOUNT IN NUMBER,
                   


        
相关标签:
1条回答
  • 2021-01-28 10:42
    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
    

    Major points

    • Oracle's number is numeric in Postgres. But if you don't have fractional digits, you'd rather use int or bigint in Postgres. About type mapping between Oracle and Postgres.

    • Postgres does not have "table types" like Oracle. Use array types, an array of numeric in this case: numeric[].

    • The expression IF p_amount_list <> '{}' ... would rule out NULL and "empty array" alike. No need for a second check like in your original. But the IF is not needed at all. For NULL or empty array, the loop isn't entered anyway.

    • r holds the element itself, not an index to it. (Therefore it must be a matching data type.)

    This goes to demonstrate basic syntax of a FOREACH loop in a plpgsql function. Otherwise it would be expensive nonsense, better replaced with a much simpler and faster:

    SELECT sum(elem) AS sum_amount
    FROM   unnest(p_amount_list) elem;
    
    0 讨论(0)
提交回复
热议问题