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

Posted

技术标签:

【中文标题】如何在postgres的函数中传递数组并修改它【英文标题】:How to pass and array and modify it in a function in postgres 【发布时间】:2018-08-23 15:45:02 【问题描述】:

我正在尝试编写一个执行此操作的函数:基本上创建一个数组,其数据元素与传递给函数的数组相同,但有时会发生一些变化——比如如果某个元素是偶数,那么标志应该从 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 中的值 - 一个在函数中定义的值。

谢谢你, 尼拉夫

【问题讨论】:

好吧,我什至无法在我的系统上创建它,它不喜欢函数的语法。但是不管怎样,你的返回值是p_nums,但你的大部分作业都是v_nums...对吗? 是的,我也只想设置 v_nums(在我通过这个问题建模的实际工作问题中,我需要打印出 v_nums)。而且我对语法非常混乱。而且我也在编辑 p_nums 一次。 【参考方案1】:

当我过去尝试做这种事情时,我遇到了类似的问题。基本上你不能使用数组表示法分配给复合对象,即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[]) 返回"(1,f)","(4,t)","(6,t)"

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

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

【讨论】:

非常感谢 Eurotrash!我在文档中没有看到任何地方指出了这些细节。这很棘手!还有一个问题。如果在函数中我想打印出传递的原始数组和修改后的数组怎么办。这可能吗? @dbusern 不确定我是否理解您所说的打印的意思 - 请参阅上面的编辑,是这样吗?由于输入和输出使用相同的数组变量,要打印原始版本,我需要在开始时调用 RAISE NOTICE,然后再进行任何修改。然后在它返回之前的最后,它再次打印修改后的数组。 嗨 Eurotrash,我明白了。我的错。我应该说的是;应用程序需要返回修改后的数组。我想你已经提供了细节。我将测试并在明天之前确认是否可行。再次感谢。 @Eurotrash。不能感谢你。它就像你说的那样工作,完全解决了我的问题。这是一个非常好的帮助。谢谢!!!!

以上是关于如何在postgres的函数中传递数组并修改它的主要内容,如果未能解决你的问题,请参考以下文章

如何通过在 swift playground 中传递 Int 数组来创建求和函数并调用它?

Postgres如何创建一个在查询中使用的函数

如何使用 Postgres 数据库 url 字符串传递证书路径以进行 SSL 连接

将数组从 node-postgres 传递给 plpgsql 函数

如何在主函数中获取整数输入并在任何类中创建该大小的数组?

如何将道具传递给递归子组件并保留所有道具