如何在 postgres 的函数中传递和数组并修改它

How to pass and array and modify it in a function in postgres

我正在尝试编写一个函数来执行此操作:基本上创建一个数组,其数据元素与传递给函数的数组相同,但有时会有一些变化——比如如果某个元素是偶数,那么标志应该改变从 N 到 Y。该过程将具有两个元素的数组作为输入 - 一个数字和一个标志。例如。 (1,'N'), (2,'N')。现在,如果传递的数字是偶数,那么 proc 应该修改该值并更改为 (2,'Y') 而另一个保持为 (1,'N')。

基本上我的数组基础知识不清楚,阅读细节也没有帮助所以这个问题。

我尝试了以下方法,但它不起作用...你能建议一下吗:

CREATE TYPE test_n_t_num AS (
v_n double precision,
is_even character varying(1));

create function temp_n_proc_2(p_nums IN OUT test_n_t_num[])
as
$$
declare
   v_nums test_n_t_num[];
     v_cnt double precision;
BEGIN
  v_cnt := cardinality(p_nums);

   v_nums := ARRAY[]::test_n_t_num[];

  for i in 1..v_cnt LOOP
   if p_nums[i].v_n_double % 2 = 0 then
      v_nums [i].is_even := 'Y';
      p_nums [i].is_even := 'Y'
   else 
      v_nums [i].is_even := p_nums [i].is_even;
   end if;

   v_nums[i] := {p_nums[i].v_n,v_nums [i].is_even};  

  END LOOP;

END;
$$
language plpgsql;

稍后我还需要遍历并打印出数组 v_nums 中的值 - 一个在函数中定义的值。

谢谢, 尼拉夫

我以前在尝试做这类事情时遇到过类似的问题。基本上你不能使用数组符号分配给复合对象,即 your_array[1].field := value 不起作用。这是一些有用的东西(我不使用 cardinality 因为我还在 9.3 上并且是在 9.4 中添加的):

CREATE TYPE public.test1 AS (a INTEGER, is_even BOOLEAN);

CREATE OR REPLACE FUNCTION f1(ar INOUT public.test1[]) AS $$
DECLARE
        t public.test1;
BEGIN
        RAISE NOTICE '%', ar;
        FOR i IN 1..ARRAY_LENGTH(ar, 1) LOOP
                t := ar[i];
                t.is_even := t.a % 2 = 0;
                ar[i] := t;
        END LOOP;
        RAISE NOTICE '%', ar;
END
$$ LANGUAGE plpgsql;

所以基本上创建一个该类型的变量,将索引项读入变量,修改字段,然后将变量的内容复制回数组。

SELECT * FROM f1('{"(1,)","(4,)","(6,)"}'::public.test1[]) returns {"(1,f)","(4,t)","(6,t)"}

打印的消息(这是使用 pgadmin 3)是:

NOTICE:  {"(1,)","(4,)","(6,)"}
NOTICE:  {"(1,f)","(4,t)","(6,t)"}