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 < 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.
ROLLBACK
inside plpgsql at all, like @Daniel already told you. A plpgsql block is always inside a transaction automatically. Any untrapped error will roll back everything automatically.