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,
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;
Can I declare a list of characters and list of numbers as function input parameters?
I have found some examples with FOREACH element
but I don't know how to grab a certain element from number list like in Oracle with p_amount_list(r)
.
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;