Step through multiple arrays in parallel with FOREACH Is it possible to loop over multiple array with FOREACH in PL/pgSQL? In my case, 3 arrays with identical dimensions. How can I pass the elements like:

for(int i = 0 ; i &lt; array1.length ; i++){
  my_method(array1[i], array2[i], array3[i]);
}


Here is my attempt:

select dugong.session_hugeInsert( 3, '5,2,3,1', '4,3,3,2');



NOTICE:  The transaction is in an uncommitable state.Transaction was rolled back.
NOTICE:  query "SELECT Question_ID, UserResponseID_List, UserResponseList" returned 3 columns 42601
ERROR:  cannot begin/end transactions in PL/pgSQL
HINT:  Use a BEGIN block with an EXCEPTION clause instead.
CONTEXT:  PL/pgSQL function dugong.session_hugeinsert(integer,text,text) line 61 at SQL statement



My function:

 CREATE OR REPLACE FUNCTION Dugong.Session_hugeInsert(
    Quiz_ID_ int,       --FK
    QuestionList_ TEXT,
    UserResponseList_ TEXT
)
RETURNS int AS $$
DECLARE
    Session_ID integer;
    QuestionList INT[];
    Question_ID integer;
    QuizQuestionisDone boolean;
    UserResponseList INT[];
    UserResponseID_List INT[];  -- Get from database
    UserResponseID integer;
    tmp int;

BEGIN
    IF EXISTS ( SELECT 1 FROM dugong.quiz WHERE quiz_id = Quiz_ID_ ) THEN

    QuestionList = string_to_array(QuestionList_, ',');
    UserResponseList = string_to_array(UserResponseList_, ',');
    FOREACH UserResponseID in ARRAY UserResponseList
    LOOP
        tmp := Dugong.UserResponse_Add();
        UserResponseID_List :=array_append(UserResponseID_List, tmp );
    END LOOP;  -- Memo: Got UserResponseID_List array

    FOREACH Question_ID, UserResponseID, tmp IN ARRAY Question_ID, UserResponseID_List, UserResponseList
    LOOP
        RAISE NOTICE '%, %, %', QuestionList[i], UserResponseID_List[i], UserResponseList[i] ;
    END LOOP;
    RETURN 200;

    ELSE
        RETURN -1;
    END IF;
END;
$$ LANGUAGE PLPGSQL;


My first solution does not seem very good:

i:=0; j:=0; k:=0;
FOREACH Question_ID IN ARRAY QuestionList
LOOP
    j := 0;
    FOREACH UserResponseID IN ARRAY UserResponseID_List
    LOOP
        k := 0;
        FOREACH tmp IN ARRAY UserResponseList
            LOOP
        IF (i = j AND j = k) THEN
           RAISE NOTICE '%, %, %', Question_ID, UserResponseID, tmp;
        END IF;
        k := k+1;
            END LOOP;
    j := j+1;
    END LOOP;
i := i + 1;
END LOOP;


Please let me know the proper way to go.
While FOREACH is very convenient to loop through a single array, it's not particularly useful to step through multiple arrays in parallel. Use a plain FOR loop with array_lower() / array_upper() instead:

FOR i IN 1 .. array_upper(UserResponseList, 1)
LOOP
   RAISE NOTICE '%, %, %', QuestionList[i], UserResponseID_List[i], UserResponseList[i];
END LOOP;


Since you created the array in the function, we know the index starts with 1 (default). Else, use:

FOR i IN array_lower(UserResponseList, 1) .. array_upper(UserResponseList, 1)


The index i is defined automatically, the documentation:


  The variable name is automatically defined as type integer and exists
  only inside the loop.


Related cases with more information:


Postgres - array for loop
To ignore result in BEFORE TRIGGER of PostgreSQL?