Postgresql

循環遍歷plpgsql函式中的二維數組切片?

  • April 19, 2018

如何遍歷函式中的數組數組並訪問其元素?

下面是函式(這只是相關部分)。

create  or replace function public.whatwhatwhy(
       _fields character varying []
   ) returns void as 
$func$
declare strSQL text := '';
declare _field text := '';
begin 
   foreach _field in array _fields[:][1:2]
       loop 
           strSQL :=  'fieldname:' || _field[1] || ' stats: ' || _field[2] ;
           raise notice '% EXECUTING %', to_char(now(), 'YYYY-MM-DD HH24:MI:SS'), strSQL;
       end loop;
end
$func$ language plpgsql;

我想用以下方法呼叫該函式:

select public.whatwhatwhy(ARRAY[
['total_pop', 'sum'],
['total_male_pop','sum'],
['median_female_age','median']
])

問題 如何在我的 中訪問例如total_popsum_field?我假設_field變數包含另一個數組但是我得到一個錯誤:

SQL 錯誤

$$ 42804 $$: 錯誤: 不能下標類型文本,因為它不是數組

其中: SQL 語句 “SELECT ‘fieldname:’ || _field$$ 1 $$|| ’ 統計數據:’ || _場地$$ 2 $$”

筆記

我試過這個說法,希望能解決問題,但好像和上面的說法一模一樣。

select public.whatwhatwhy(ARRAY[
ARRAY['total_pop', 'sum'],
ARRAY['total_male_pop','sum'],
ARRAY['median_female_age','median']
])

感謝評論者。

這個 SE 答案最終幫助我解決了問題。

  • _field不需要聲明。
  • foreach循環變成一個簡單的循環。
  • 每個欄位由[i][1]列名(例如total_pop)[i][2]統計資訊(例如sum )定址。

該功能必須是這樣的:

create  or replace function public.mj_rubbish(
       _fields character varying []
   ) returns void as 
$func$
declare strSQL text := '';
begin 
   for i in 1 .. array_upper(_fields,1)
       loop 
           strSQL :=  'fieldname:' || _fields[i][1] || ' stats: ' || _fields[i][2] ;
           raise notice '% EXECUTING %', to_char(now(), 'YYYY-MM-DD HH24:MI:SS'), strSQL;
       end loop;
end
$func$ language plpgsql;

將輸出:

00000:2018-04-06 12:08:53 執行欄位名:total_pop 統計資訊:總和

00000:2018-04-06 12:08:53 執行欄位名稱:total_male_pop 統計資訊:總和

00000:2018-04-06 12:08:53執行欄位名:median_male_age 統計:中位數

00000:2018-04-06 12:08:53 執行欄位名:median_female_age 統計:中位數

像您發現的那樣FOR循環array_upper(_fields,1)是一個簡單而好的選擇。

對於您的情況(對於 Postgres 9.1 或更高版本)更簡單:FOREACH使用SLICE. 手冊:

使用正值SLICEFOREACH遍歷數組的切片而不是單個元素。

您的函式可能如下所示:

CREATE OR REPLACE FUNCTION public.mj_rubbish(_fields text[])
  RETURNS void AS
$func$
DECLARE
  m text[];
BEGIN
  FOREACH m SLICE 1 IN ARRAY _fields
  LOOP
     RAISE NOTICE '% EXECUTING fieldname: %, stats: %', now()::text, m[1], m[2];
  END LOOP;
END
$func$  LANGUAGE plpgsql;

無論實際的數組索引如何,這也有效 - 不必以1開頭(但預設情況下)。

有關的:

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