如何在postgres中的函数中传递和数组以及对其进行修改

时间:2018-08-23 15:45:02

标签: postgresql plpgsql stored-functions

我正在尝试编写一个执行此操作的函数:基本上创建一个数组,该数组具有与传递给该函数的数组相同的数据元素,但有时会有所更改-就像某个元素是偶数,则该标志应从N更改该过程将一个包含两个元素的数组作为输入:一个数字和一个标志。例如。 (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中的值-该数组在函数中定义。

谢谢你, 尼拉夫

1 个答案:

答案 0 :(得分:0)

当我试图回想过去的事情时,我遇到了类似的问题。基本上,您不能使用数组符号分配给复合对象,即your_array[1].field := value不起作用。这是可以做的事情(因为我仍然使用9.3,所以我不使用cardinality,并且在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[])返回{"(1,f)","(4,t)","(6,t)"}

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

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