问题 并联多个阵列


我的上一个问题 传递数组到存储到postgres 有点不清楚。现在,澄清我的目标:

我想创建一个Postgres存储过程,它将接受两个输入参数。一个将是一些列表  比如说 (100, 40.5, 76) 而另一个将列出一些 发票  ('01-2222-05','01-3333-04','01-4444-08')。之后,我想使用这两个数字和字符列表,并用它们做一些事情。例如,我想从这个数字数组中取出每个金额并将其分配给相应的发票。

在Oracle中类似的东西看起来像这样:

SOME_PACKAGE.SOME_PROCEDURE (
    789,
    SYSDATE,
    SIMPLEARRAYTYPE ('01-2222-05','01-3333-04','01-4444-08'), 
    NUMBER_TABLE (100,40.5,76),
    'EUR',      
    1, 
    P_CODE,
    P_MESSAGE);

当然,这两种类型 SIMPLEARRAYTYPE 和 NUMBER_TABLE 在DB中早先定义。


8130
2018-01-08 09:22


起源

有什么不清楚的?如何 呼叫 这些功能?您可以使用数组构造函数 postgresql.org/docs/current/static/... 或者,您可以在字符串中写入他们的输入表示(然后使用可选的铸造) postgresql.org/docs/current/static/arrays.html#ARRAYS-IO - pozs
我不知道如何使用这些输入参数创建存储过程。 - Maki
这也包含在您之前的问题中(f.ex. stackoverflow.com/questions/27708234/... ) - 您可以使用标准兼容 <type> ARRAY,或PostgreSQL特定的 <type>[] 句法。 postgresql.org/docs/current/static/... - pozs


答案:


你会  Postgres的这个新功能 9.4

    不需要的(anyarray,anyarray [,...])

unnest() 非常期待(至少是我)能够并行排除多个阵列 干净手册:

将多个数组(可能是不同类型)扩展为一组行。这只能在FROM子句中使用;

这是新的特殊实现 ROWS FROM 特征

你的功能现在可以是:

CREATE OR REPLACE FUNCTION multi_unnest(_some_id int
                                      , _amounts numeric[]
                                      , _invoices text[])
  RETURNS TABLE (some_id int, amount numeric, invoice text) AS
$func$
SELECT _some_id, u.* FROM 不需要的(_amounts,_invoices) u;
$func$ LANGUAGE sql;

呼叫:

SELECT * FROM multi_unnest(123, '{100, 40.5, 76}'::numeric[] 
                        , '{01-2222-05,01-3333-04,01-4444-08}'::text[]);

当然,简单的形式可以替换 纯SQL (没有附加功能):

SELECT 123 AS some_id, *
FROM unnest('{100, 40.5, 76}'::numeric[]
          , '{01-2222-05,01-3333-04,01-4444-08}'::text[]) AS u(amount, invoice);

在早期版本(Postgres 9.3-),你可以使用不那么优雅和不太安全的形式:

SELECT 123 AS some_id
     , unnest('{100, 40.5, 76}'::numeric[]) AS amount
     , unnest('{01-2222-05,01-3333-04,01-4444-08}'::text[]) AS invoice;

旧速记形式的注意事项:除了具有设置返回功能的非标准之外 SELECT list,返回的行数将是每个数组元素数的最低公倍数(对于不等数字,结果令人惊讶)。这些相关答案的详细信息:

这种行为终于被消毒了 Postgres 10。多个集合返回函数 SELECT list现在在“lock-step”中生成行。看到:


13
2018-01-09 05:28



文档中“行来自”语法的文档有点令人困惑,没有示例。仅供参考 select * from rows from(unnest('{1,2,3}'::integer[]), unnest('{4,5,6}'::integer[]), unnest('{7,8}'::integer[])) u(a, b, c); 将演示基本用法 - “rows from”构造返回一个可以在from子句中使用的表。 - Simon D


通过添加声明数组 [] 到基数据类型。您将它们声明为参数,与声明常规参数的方式相同:

以下函数接受整数数组和字符串数组,并返回一些虚拟文本:

create function array_demo(p_data integer[], p_invoices text[])
  returns text
as
$$
  select p_data[1] || ' => ' || p_invoices[1];
$$
language sql;

select array_demo(array[1,2,3], array['one', 'two', 'three']);

SQLFiddle演示: http://sqlfiddle.com/#!15/fdb8d/1


2
2018-01-08 09:59



我尝试这个电话时遇到错误。 - Maki
对不起,我的错误,没关系。你可以在文本数组上使用FOREACH吗? - Maki
我可以在Postgres中使用FOREACH而不是文本数组吗? - Maki
@Maki:如果其他一切都失败了,请阅读手册: postgresql.org/docs/current/static/... - a_horse_with_no_name