Postgresql

使用 FOREACH 並行遍歷多個數組

  • August 3, 2021

FOREACH是否可以在 PL/pgSQL中循環多個數組?在我的情況下,3個具有相同尺寸的數組。我怎樣才能傳遞這樣的元素:

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

這是我的嘗試:

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

我的功能:

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;

我的第一個解決方案似乎不是很好:

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;

請讓我知道正確的方法。

雖然循環遍歷單個數組FOREACH非常方便,但並行遍歷多個數組並不是特別有用。使用帶有/的普通循環:FORarray_lower()``array_upper()

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

由於您在函式中創建了數組,我們知道索引從 1 開始(預設)。否則,使用:

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

索引i是自動定義的,文件:

該變數**name**被自動定義為類型integer並且僅存在於循環內部。

相關案例及更多資訊:

引用自:https://dba.stackexchange.com/questions/111410