71

In plpgsql, I want to get the array contents one by one from a two dimension array.

DECLARE
  m varchar[];
  arr varchar[][] := array[['key1','val1'],['key2','val2']];
BEGIN
  for m in select arr LOOP
    raise NOTICE '%',m;
  END LOOP;
END;

But the above code returns:

{{key1,val1},{key2,val2}}

in one line. I want to be able to loop over and call another function which takes parameters like:

another_func(key1,val1)
0

2 Answers 2

151

Since PostgreSQL 9.1

There is the convenient FOREACH which can loop over slices of arrays. The manual:

The target variable must be an array, and it receives successive slices of the array value, where each slice is of the number of dimensions specified by SLICE.

DO
$do$
DECLARE
   m   text[];
   arr text[] := '{{key1,val1},{key2,val2}}';  -- array literal
BEGIN
   FOREACH m SLICE 1 IN ARRAY arr
   LOOP
      RAISE NOTICE 'another_func(%,%)', m[1], m[2];
   END LOOP;
END
$do$;

db<>fiddle here - with a function printing results, instead of DO

LANGUAGE plpgsql is the default for a DO statement so we can omit the declaration.

There is no difference between text[] and text[][] for the Postgres type system. See:

Postgres 9.0 or older

DO
$do$
DECLARE
   arr text[] := array[['key1','val1'],['key2','val2']];  -- array constructor
BEGIN
   FOR i IN array_lower(arr, 1) .. array_upper(arr, 1)
   LOOP
      RAISE NOTICE 'another_func(%,%)', arr[i][1], arr[i][2];
   END LOOP;
END
$do$;
Sign up to request clarification or add additional context in comments.

2 Comments

How do we run this dynamically, for eg if we have array arr with n items, we need to raise notice n time for each item.
@CherrylRarewings: I suggest you start a new question with your specifics. You can always link to this one for context.
0

You can use a FOREACH statement to iterate a 2D array as shown below:

DO $$
DECLARE
  temp VARCHAR;
  _2d_arr VARCHAR[] := ARRAY[
    ['a','b','c'],
    ['d','e','f']
  ];
BEGIN
  FOREACH temp SLICE 0 IN ARRAY _2d_arr LOOP
    RAISE INFO '%', temp;
  END LOOP;
END
$$;

Or, you can use a FOR statement to iterate a 2D array as shown below:

DO $$
DECLARE
  _2d_arr VARCHAR[] := ARRAY[
    ['a','b','c'],
    ['d','e','f']
  ];
BEGIN
  FOR num1 IN 1..2 LOOP
    FOR num2 IN 1..3 LOOP
      RAISE INFO '%', _2d_arr[num1][num2];
    END LOOP;
  END LOOP;
END
$$;

Then, you can iterate the 2D array as shown below:

INFO:  a
INFO:  b
INFO:  c
INFO:  d
INFO:  e
INFO:  f
DO

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.