我在一个函数中初始化了两个数组,一个用于数字(数量列表),另一个用于文本(发票列表)。我想从这个函数调用另一个函数并将这两个数组作为参数传递 我可以这样调用函数,一切正常:
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[]) ...
答案 0 :(得分:1)
您可以像这样修复您的功能:
CREATE OR REPLACE FUNCTION function_1(in_account int
, OUT out_code1 int
, OUT out_message1 text)
RETURNS RECORD AS
$func$
DECLARE
counter int := 1; -- 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 -- !!!
ORDER BY "ID" -- 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 f.outfield_1, f.outfield_2 -- replace with actual names!
INTO out_code1, out_message1
FROM function_2(invoice_list, amount_list) f;
END
$func$ LANGUAGE plpgsql VOLATILE
必须初始化函数变量计数器或将其设置为NULL。
in_account
被解释为表格"INVOICE"
的列名称(它可能不是)。似乎缺少一个功能参数。
将我添加的ORDER BY "ID"
替换为您实际需要的排序顺序。
您需要分配最终SELECT
的结果。
invoice_list
和amount_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函数中。