arrays - 将数组变量作为参数传递给另一个函数

标签 arrays postgresql parameter-passing plpgsql stored-functions

我在一个函数中初始化了两个数组,一个用于数字(金额列表),另一个用于文本(发票列表)。我想从这个函数调用另一个函数并将这两个数组作为参数传递。
我可以这样调用函数,一切正常:

select function_2('{110011-0115-7}'::text[], '{100}'::numeric[])

但是当我想发送一个包含文本数组的变量时,该数组似乎是空的:

select function_2(ARRAY[invoice_list], ARRAY[amount_list]);

函数定义:

CREATE OR REPLACE FUNCTION function_1(OUT out_code1 integer
                                    , OUT out_message1 text)
  RETURNS RECORD AS
$BODY$
DECLARE
   counter      numeric;
   inv_cur      record;
   invoice_list text[];
   amount_list  numeric[]; 
BEGIN
   FOR inv_cur IN
      SELECT "ID", "AMOUNT"
      FROM "INVOICE"
      WHERE "ACCOUNT_ID" = in_account
   LOOP
       --Adding invoices to invoice array
        invoice_list[counter] := inv_cur."ID";

        --Adding amounts to amount array
        amount_list[counter] := inv_cur."AMOUNT";

        --Increasing counter for array indexes
        counter := counter + 1;
   END LOOP;

   --Caling other function
   SELECT * FROM function_2(ARRAY[invoice_list], ARRAY[amount_list]);
END
$BODY$
  LANGUAGE plpgsql VOLATILE

其他函数定义:

 CREATE OR REPLACE FUNCTION function_2(in_invoices text[]
                                     , in_amounts numeric[]) ...

最佳答案

你可以像这样修复你的函数:

CREATE OR REPLACE FUNCTION function_1(<b>in_account int</b>
                                , OUT out_code1 int
                                , OUT out_message1 text)
  RETURNS RECORD AS
$func$
DECLARE
   <b>counter    int := 1;</b>  -- use int and initialize
   inv_cur      record;
   invoice_list text[];
   amount_list  numeric[]; 
BEGIN

   FOR inv_cur IN
      SELECT "ID", "AMOUNT"
      FROM   "INVOICE"
      WHERE  "ACCOUNT_ID" = in_account  -- !!!
      <b>ORDER  BY "ID"</b> -- don't you care about sort order?
   LOOP
       --Adding invoices to invoice array
        invoice_list[counter] := inv_cur."ID";

        --Adding amounts to amount array
        amount_list[counter] := inv_cur."AMOUNT";

        --Increasing counter for array indexes
        counter := counter + 1;
   END LOOP;

   --  Calling other function
   SELECT <b>f.outfield_1, f.outfield_2</b>  -- replace with actual names!
   <b>INTO  out_code1, out_message1
   FROM  function_2(invoice_list, amount_list) f</b>;

END
$func$  LANGUAGE plpgsql VOLATILE

注意事项

  • 函数变量 counter 必须初始化或设置为 NULL。

  • in_account 被解释为表 "INVOICE" 的列名(它可能不是)。似乎缺少函数参数。

  • 将我添加的 ORDER BY "ID" 替换为您实际需要的排序顺序。

  • 需要分配最终 SELECT 的结果。

  • invoice_listamount_list 已经是数组。如果你想添加另一个数组维度,只将它们包装到另一个 ARRAY 层中(我对此表示怀疑。)

现在函数应该工作了。还是昂贵的废话 ...

以您的方式处理数组非常昂贵。循环也很昂贵。将 function_1() 替换为以下查询:

SELECT f.*
FROM  (
   SELECT function_2(array_agg("ID"), array_agg("AMOUNT")) AS f
   FROM  (
      SELECT "ID", "AMOUNT"
      FROM   "INVOICE"
      WHERE  "ACCOUNT_ID" = in_account  -- your input here!
      ORDER  BY "ID"
      ) t1
   ) t2;

您可以使用单个查询级别:

SELECT (function_2(array_agg("ID" ORDER BY "ID")
                 , array_agg("AMOUNT" ORDER BY "ID"))).*
FROM   "INVOICE"
WHERE  "ACCOUNT_ID" = in_account;

但是性能会差很多。带有子查询的版本只需要排序一次并且也只调用函数一次:

如果需要,您可以将其包装到 SQL 函数中。

关于arrays - 将数组变量作为参数传递给另一个函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31321276/

相关文章:

c - 动态字符串数组/动态字典

arrays - Tcl v8.4 中让 proc 返回数组的最佳方法是什么?

arrays - 将 JSONB_ARRAY_ELEMENTS 结果分配给 VARCHAR 数组

php - 根据发送的参数进行动态重定向php

c - 如何更改 C 函数中的结构变量?

java - Java是“按引用传递”还是“按值传递”?

c - 测试 2 次刺痛是否有相同的单词 (C)

javascript - 如何在javascript中展平包含对象的多维数组

ruby-on-rails - Rails 4 - 为表单中关联表中的行分配值

sql - 查找哪个列导致查询中的 postgresql 异常。