与 FOREACH 并行遍历多个数组

Sar*_*rit 6 postgresql plpgsql array

是否可以FOREACH在 PL/pgSQL 中循环多个数组?就我而言,3 个具有相同维度的数组。我如何传递元素,如:

for(int i = 0 ; i < array1.length ; i++){
  my_method(array1[i], array2[i], array3[i]);
}
Run Code Online (Sandbox Code Playgroud)

这是我的尝试:

select dugong.session_hugeInsert( 3, '5,2,3,1', '4,3,3,2');
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)

我的功能:

 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;
Run Code Online (Sandbox Code Playgroud)

我的第一个解决方案似乎不太好:

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;
Run Code Online (Sandbox Code Playgroud)

请让我知道正确的方法。

Erw*_*ter 5

虽然FOREACH循环遍历单个数组非常方便,但并行遍历多个数组并不是特别有用。使用FOR带有array_lower()/array_upper()的普通循环代替:

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

由于您在函数中创建了数组,我们知道索引从 1(默认)开始。否则,使用:

FOR i IN array_lower(UserResponseList, 1) .. array_upper(UserResponseList, 1)
Run Code Online (Sandbox Code Playgroud)

索引i是自动定义的,文档:

该变量name被自动定义为类型integer并且仅存在于循环内。

提供更多信息的相关案例: